C# Accumulate mentor guidance issue

Hi everyone,

I put this topic in the general C# thread because it involves some trouble I have with laziness (of a method, not of me!)

In the mentoring guidance for the Accumulate exercise, one solution doesn’t involve the yield keyword:

using System;
using System.Collections.Generic;

public static class AccumulateExtensions
{
    public static IEnumerable<U> Accumulate<T, U>(this IEnumerable<T> collection, Func<T, U> func)
    {
        var accumulated = new List<U>();

        foreach (var element in collection)
        {
            accumulated.Add(func(element));
        }

        return accumulated;
    }
}

Yet, this solution doesn’t pass the test cases, as the solution is required to be lazy:

Laziness test

Since accumulate returns an IEnumerable, it’s execution is deferred until ToList() it is called on it, which is tested with the Accumulate_is_lazy method

With the following test:

var counter = 0;
var accumulation = new[]
        {
            1,
            2,
            3
        }.Accumulate(x => x * counter++);
Assert.Equal(0, counter);
accumulation.ToList();
Assert.Equal(3, counter);

Which returns for the given guidance solution:

Assert.Equal() Failure
Expected: 0
Actual:   3

I’m pretty new to lazy evaluations: is there a way to edit the guidance example method in a simple way that leads to it being lazy?
I’d be happy to submit a PR for addressing this issue but I don’t know how to solve it yet, I’d appreciate if someone could point me to some reading about it!

I can only think of writting a custom Enumerator that implements IEnumerator, but that makes the solution way more complicated and I guess anyone would use yield return over it?

It there isn’t a simple way to make the guidance method lazy, maybe the simplest way to address the issue is to delete the ### Storing the results in an intermediate list section of the mentor guidance?

Thanks!

The only non-yield option I can think of is to manually create an iterator, but I don’t think that makes a lot of sense (and would be more work).

What I think needs to be done is to update the mentoring notes to not suggest the non-yield version. I think it might still be useful to have the non-yield version in the mentoring notes, but then with an explicit mention that it doesn’t pass the tests.

Would you be up for changing the mentoring notes? They’re found here: website-copy/tracks/csharp/exercises/accumulate/mentoring.md at main · exercism/website-copy · GitHub

Thanks Erik,

I agree with you, I’ll happily edit the mentoring notes and submit a PR. Thanks for answering!

I noticed in the repo that the guidance for the Accumulate exercise in F# has the same “If the student doesn't use the yield keyword, suggest them to look into it” statement: does the same modification apply here? (I skipped the 12in23 challenge and don’t know anything about F#!! :expressionless:)

1 Like

I’m positive it does hold for F# too!

1 Like

I justed submitted the PR. I didn’t touch the F# guidance, as there is nothing about Lazy expression in the exercise overview.

Great! Merged the PR.

1 Like

Cool, thanks!

I also opened a PR on the exercism/csharp repo (#2241) that fix some typos on the C# overview of the exercise, I didn’t bother creating a new topic on the forum because it only fixed a small typo and a faulty hyperlink.

1 Like

That’s perfectly fine.

1 Like