Could Python supplant Java?
joeking at merseymail.com
Wed Aug 28 13:46:58 CEST 2002
Duncan Booth <duncan at NOSPAMrcp.co.uk> wrote in message news:<Xns92776E89D3A01duncanrcpcouk at 127.0.0.1>...
> Well, it is a personal thing, but I would go for the following as being
> more readable/maintainable than either of yours:
> >>> def printIt(x):
> print "Your",type(x).__name__,"is",x
> >>> printIt(5)
> Your int is 5
> >>> printIt('hello')
> Your str is hello
> Oh dear, I seem to have lost that 'huge switch statement' somewhere. Oops.
Yeah - only because the example was so simplistic. :-)
> Seriously though, a lot of generic fuctions will collapse down to identical
> code when you use a dynamically typed language like Python. It is probably
> even a good rule to say that if they don't collapse then you should have
> separate functions with different names to show clearly that they are doing
> different things.
And likewise a lot of overloaded methods are actually just wrappers
around a single method - all they do is manipulate their arguments
and call the main method. Which is no harder on the keyboard than
what you describe.
Of course, it does have the added benefit of explicitly listing all
the types of data which this method can accept. Readability? :-)
> Where on earth did you get the idea that unit tests mean you put lots of
> useless asserts into your code? This is just silly.
> I'll have to guess what your WordWrap function is supposed to do, but I
> suspect my equivalent would be:
> def WordWrap(breakchars, source, width):
> '''Implementation goes here'''
> class TestWordWrap(unittest.TestCase):
> def testSimpleWrap(self):
> WordWrap(' ', 'The quick brown fox jumps over the lazy dog', 10),
> ['The quick', 'brown fox', 'jumps over', 'the lazy', 'dog'])
> I would note the following points:
> I didn't have to separately assert the type of the result, that check comes
> free when I check that the value of the result is what I expected.
All you have checked here is that your function returns a valid
result if you pass it valid arguments.
That's important, of course, but rather simplistic. A very hefty
proportion of errors come when invalid or unexpected data is passed
into a piece of code. ie. you feed in -99 as someone's age, or ""
(empty string) as someone's name. With dynamically typing you have
the added complication of having to deal with "" as someone's age
and -99 as someone's name.
The assertions are necessary, because the programmer calling my
code may well have transposed the arguments, or simply provided
the wrong types. On 'big projects' the chances are I will be
writing code which will (a) be called by someone else's code and/or
(b) be maintained by a team rather than a single programmer.
Unit tests are handy for checking that the internals of a function
are (reasonably) valid. Static types can check that the 'interfacing'
of that function into other code is (reasonably) valid. When you
are writing small scripts, interfacing isn't an issue - the code is
too small and compact for issues like that to arise. When you are
writing huge applications with several programmers, trapping
'interfacing' problems (passing bogus or incorrect data) is a
problem. Static types help solve some of that problem.
> I haven't checked that the callers of this function are passing in suitable
> parameters. That is because I'm not testing them, I'm testing WordWrap
> here, and anything that uses it will get tested elsewhere later.
So you end up writing the test code anyway, it just gets shifted
Hard Fact of Life Number 6234 (in a series of near infinity) : if
your function produces garbage out when someone pumps garbage in,
your boss will blame you as much as the shmuck programmer who used
your function. If you are more senior than him, he will blame you
more. (Yeah yeah - but life *ain't* fair! :-)
Bottom line is that the tests to check for valid argument types
still has to be done for any software which is non-trivial. If
I define the types within the code, they serve as documentation to
the programmer calling my code, and they allow some checks to be
done by the compiler. There's still plenty of oppotunity for me
to produce 'garbage out' - but at least the ground is more stable
> It also occurs to me to wonder whether this WordWrap is supposed to do a
> greedy word wrapping (the way most word processors do), or a nicely
> balanced one the way TeX does. This is the sort of thing that gets
> overlooked until you come to write the tests. It may not be important to
> the customer, but perhaps it is.
Check the spec. It'll be in there :-)
[snipped stuff about Challenger...]
> And statically typed languages help with this precisely how?
Nothing. As I explained in the original post, it was an aside
about testing in general (and placing too much faith in it,
> Actually, I seem to remember that NASA knew perfectly well that temperature
> was critically important to their o-rings. Didn't they go ahead with that
> launch in spite of their own rules which should have cancelled it?
I don't think they deliberately blew up a space shuttle. They did
the test and they knew the results - but they didn't understand the
importance of the results in the circumstances. It was a classic
case of what I outlined above - they did a specific sets of tests
(unit tests) with a specific set of conditions (test data) and they
determined the operational parameters of the o-ring components. On
the day of the launch an extra factor was brought into play which
they hadn't considered during their unit tests - the night before
had been very windy and cold, and that had affected the o-rings
NASA, for all its checking and testing and billion dollar budgets
still ended up with a classic GIGO error - unexpected data was
fed into the situation (the temperature the night before) and the
results from all the unit test were suddenly worth naught. NASA's
mistake I guess (against the wishes of the contractors who made
the o-rings IIRC) was to trust the test data. They trusted in
their own ability to correctly identify *all* the ways a
component could fail.
The lesson is, I would assume, that testing - no matter how
strict, how intensive and how meticulous - will never stop
errors from getting through. The advantage of static typing
is that it imposes a disipline on the programmer which just
lessens the burden of having to trap all those bugs in testing.
Or to put it another way: as testing is not a precise science,
you should attempt to stop as many bugs from getting to the
testing stage as possible.
The usual caveat about dynamic/static typing applies (see
my previous messages in this thread! :-)
More information about the Python-list