
Special Cases Are a Code Smell - jonahx
https://blog.conjur.org/special-cases-are-a-code-smell/
======
eesmith
When there are multiple code smells, which should have preference?

FWIW, the "straightforward approach" is invalid when the list contains only
one element, which helps support the argument that special cases are code
smells.

However, the suggested solution - padding - assumes that such solutions are
possible. That is, it assumes that there is enough memory to duplicate the
array, and introduces a full copy as all the data is transferred, potentially
twice. The result might be measurably and noticeably slower. There's also the
overhead of instantiating the iterator object via map.with_index, and the
double array indexing for each value - which may be slow depending on how the
object implements array indexing.

I consider those to also be code smells, and worse code smells than special
casing.

The following Python code also has special cases, because of the two 'yield'
statements. However, it has none of the above mentioned downsides of the
proposed proposed solution:

    
    
      def neighbor_sum(values):
         value_iter = iter(values)
         left = 0
         mid = next(value_iter)
         for right in value_iter:
            yield left + right
            left, mid = mid, right
         yield left
    

As far as I can tell, it produces the same results. It should also be faster
and lighter in memory use than the equivalent Python implementation of the
proposed solution.

The 'Down with evens' example is also going to be slower than it "should" be,
because it creates and destroys unneeded temporaries. The argument is that
"conceptually map is a better fit", but as a Python user I would implement it
like:

    
    
      def down_with_evens(data_list):
        for x in data_list:
          if len(x) % 2 == 0: # even
             yield [x[0]]
             yield x[1:]  # or 'del x[0]; yield x' to match the original
          else:
             yield x
    

Isn't that clearer, and without the code smell of unneeded object creation
causing performance slowdowns? Does Ruby have something comparable?

