On 02/11/2011 10:33 PM, Andrei Alexandrescu wrote:
On 2/11/11 1:52 PM, spir wrote:
On 02/11/2011 08:20 PM, Steve Schveighoffer wrote:
At some point, factoring out repetitive code becomes more harmful than
the alternative. I feel like unit tests are one of those cases.

Hum, had a similar thought recently. I started to "unfactor out" some
pieces of code into very basic caller funcs (the kind that constantly
get called, thus would appear on top of a profiler's output in terms of
number of executions). The initial reason was lack of knowledge about
whether the tool funcs would be inlined or not (reason for the other
thread).
Then, I realised the result is sometimes easier to understand, provided
the initially factored out part is properly "titled" by a comment,
especially when it is non-obvious to identify as a kind of sub-task.

Consider the code below. It is a simplification of 60 lines of code in
std.datetime, which I paste at the end of this message. The code is formatted
at 80 columns, at the same time showing that you can write compact _and_ good
_and_ simple _and_ effective code in 80 columns. (It wraps in the email because
email wraps at 75 columns or so.)

The space taken is 24/60 lines = 40%. Less than half of the original - all with
generous indentation and narrow columns. Clarity greatly gained, bulk saved,
maintenance simplified, failure clarified, and your shoes are shiny. "What else
can we do?" Really if there's any debate that this is not a huge improvement I
give up. Behead me.

     unittest
     {
         auto badDates =
             [
                 "", "990704", "0100704", "2010070", "2010070 ",
                 "120100704", "-0100704", "+0100704", "2010070a", "20100a04",
                 "2010a704", "99-07-04", "010-07-04", "2010-07-0", "2010-07-0 ",
                 "12010-07-04", "-010-07-04", "+010-07-04", "2010-07-0a",
                 "2010-0a-04", "2010-a7-04", "2010/07/04", "2010/7/04",
                 "2010/7/4", "2010/07/4", "2010-7-04", "2010-7-4", "2010-07-4",
                 "99Jul04", "010Jul04", "2010Jul0", "2010Jul0 ", "12010Jul04",
                 "-010Jul04", "+010Jul04", "2010Jul0a", "2010Jua04", 
"2010aul04",
                 "99-Jul-04", "010-Jul-04", "2010-Jul-0", "2010-Jul-0 ",
                 "12010-Jul-04", "-010-Jul-04", "+010-Jul-04", "2010-Jul-0a",
                 "2010-Jua-04", "2010-Jal-04", "2010-aul-04", "2010-07-04",
                 "2010-Jul-04",
             ];

         foreach (badDate; badDates)
         {
             assertThrown!DateTimeException(Date.fromISOString(badDate),
                 "Accepts bad date: " ~ badDate);
         }
     }


Andrei

Agreed :-) (sure)

<ot>
The type of things I had in mind is this kind of little tool funcs we sometimes write to externalise a difficult point in a dark corner of a useful func (guess you know what I mean). I often do that. That sort of hard point is usually not easy just to spot, delimit, and define clearly, let alone naming it in such a way that months later we have a chance to re-realise what the need for this func was, how it was designed and how it is supposed to be used, exactly. Factorising out also sometimes /increases/ complexity, forcing for instance to add one or two more params, like ref'ed indices or such, which do not belong to the model, and correspond to data which are "just here" when not externalised. If, in addition to those problems, and in case of a core functionality (it's often there that such issues raise) called millions of times, one cannot know whether that tool func will be inlined or not... I now tend to just let things in place.
</ot>

Denis
--
_________________
vita es estrany
spir.wikidot.com

_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos

Reply via email to