Series in Rust: Wrong test case?

There was a mentoring request asking for correctnes of the first test case. The test wants the empty substrings and the result is a vector of length 6. The student asks if this shouldn’t be of length 5. I would even say, it should be of length 1 with element “”. At least that seems to be the test case for C. In TypeScript this case is not even valid. In Go is no case for this.

Exercise: Series in Rust on Exercism
The test in question: rust/series.rs at ef74a61dfd7783037df1e4eb801772008eb17182 · exercism/rust · GitHub

The test is

fn test_with_zero_length() {
    let expected = vec!["".to_string(); 6];
    assert_eq!(series("92017", 0), expected);
}

It is correct. Here are the 6 empty substrings:

 9 2 0 1 7
↑ ↑ ↑ ↑ ↑ ↑ 

In general, the number of substrings is length(string) - span + 1. The other tests reflect this as well.

This pattern allows using recursion/induction over the span to solve this problem.

I see why it should be 6 for this exercise and solution. But when 6 is correct, it should be correct in all languages.

  xit('slice length cannot be zero', () => {
    expect(() => {
      new Series('12345').slices(0)
    }).toThrow(new Error('slice length cannot be zero'))
  })
   char *substrings[] = { "" };
   slices_t expected = { 0, &substrings[0] };
   slices_t actual = slices("12345", 0);

If you ask me, if other tracks have other opinions on this question then they are morally in the wrong. (Though I am somewhat sympathetic to requiring partiality at span 0.)

Why should it be 1 empty substring? Also, why is that a good fit for C specifically? Edit: sorry, I misread “test” as “best”.

The C track requires returning a single empty string for all ‘invalid’ inputs. The test about span 0 is named test_slice_length_cannot_be_zero; it seems the C track thinks empty span is invalid.

I agree with both: invalid and length of 6. But I would recommend to handle that in all languages the same.

Turns out it already is standardised: problem-specifications/canonical-data.json at f699acb5195bf513a9844d9539a9113ab27794f9 · exercism/problem-specifications · GitHub

This was discussed from this comment onwards. However, though there is an entry in the canonical data, I do not think the issue has ever been truly decided. There has been discussion (leaning towards accepting 0 spans), but I cannot find its resolution. The initial proposal might have been merged by default.

Oh, great, thank you. I wasn’t aware of this canonical definition. With this it’s invalid and the Rust tests should be modified. Right?

Nope. Tracks are free to deviate from the canonical data. This is specified somewhere but I cannot find it right now.

Note that in the linked PR it is argued that and why Rust should accept empty spans and prohibit errors.

:hushed: Well, ok. :wink: For such absolute results, I would expect the same in each language. But when that’s intended, it is like it is.

I see that it shouldn’t be an error. But that it should be of length 6 (for Rust) is not described. I even guess this is more a philosophical problem, than a technical. And with that it still could be the same in all languages.

It certainly could be the same across language. But track maintainers are also allowed to have strong opinions and disagree on topics. They are also allowed to not follow the problem specs when they feel the specs don’t fit that particular language’s model. The specs are a strong guidance, but not the final say.

It is argued generally. (But yeah, not for Rust specifically.)

This issue is reminiscent of the empty product and the zero exponent being 1, the empty sum being 0, and 0! = 1.

This issue is dissimilar to x ÷ 0 = 37.