Xy Symmetry Bugs

Symptom: The code works in the X direction but not in the Y direction, or vice versa. Or both directions are wrong, but in different ways.

Probable Cause: Too much copy and paste.

Discussion: This often happens when there is enough X/Y symmetry to make me want to reuse algorithms, but enough difference to prevent direct reuse.

For example, a spreadsheet will have a tab control along the top and left side. A lot of the code for the horizontal case will be the same as code for the vertical case but with the Xes and Ys swapped around. However, text will be drawn from left to right in both, so the Xes and Ys to do with text don't get swapped.

In a case like that, it can be easiest to copy the code and edit the bits which need to be edited. This leads to bugs where an X or a Y gets left unchanged.

To some extent you can make abstractions and factor the code out into a base class. Certainly you should do that. But the difference between X and Y has to be represented somewhere, so at some point you will have lines of code that are identical apart from the Xes and Ys.

Why it matters: The point here is that cut and paste produces code which is correct as far as the compiler is concerned. It'll have correct syntax and will pass the static type-checker. It will often look OK to the human eye, too. It's only when you run the code that you notice the behaviour is wrong.

See also: CopyAndPasteProgramming, SourcesOfBugs.

-- DaveHarris


One of my collaborators is particularly vulnerable to this type of bug. He writes some tests to exercise the code, but invariably supplies the tests with arguments that exhibit XySymmetry?.

And then there was the occasion when, after six months of development, somebody finally attempted to create a user where the password differed from the userid....


A tool to help against this is quasiquotation (as it is known in SchemeLanguage, other names in other languages?)

Quasiquote is a fill-in-the-blanks kind of macro. It's "backquote" in CommonLisp, and "segment" (or "splice") in the old MDL dialect of Lisp. I don't recall seeing anything similar in any other language, except for text-with-embedded-variables approach to web pages, script language strings, etc, which isn't what this page is really about. But generic functions in many languages, and C++ templates, allow somewhat similar things: higher degree of parameterizing a single copy of code rather than being forced to create two similar functions.


An untested approach (but now that I've had the idea, I'm likely to try applying it to my table code) would be to maintain several lists of x-y dependant code, which will always maintain the same alignment. The idea being that one could shift the x-y of one list via a method call or flag change, while leaving the other(s) uneffected.

--WilliamUnderwood


One approach is to look at your factoring. Continuing the spreadsheet example: Each tool button has an origin, or a rectangle, or some such boundary. One concern is to compute the sequence of button boundaries, and another is to render (or figure the size of) the individual buttons. The second part doesn't change depending on orientation, so it can (and probably should) be factored elsewhere from the part that computes either a horizontal or a vertical sequence of origins. Do that, suddenly the bug is a lot more transparent. Further, I'm sure there are other places where you have either or both of horizontal or vertical stacking of subordinate regions. Perhaps we can apply OAOO to the more general problem and avoid even the opportunity to repeat the bug. --IanKjos


CategoryBug


EditText of this page (last edited November 20, 2014) or FindPage with title or text search