Re: Static vs. Dynamic typing (big advantage or not)---WAS: c.programming: OOP

From: Dave Harris (brangdon_at_cix.co.uk)
Date: 07/17/04


Date: Sat, 17 Jul 2004 16:37 +0100 (BST)

cristianoTAKEsadun@THIShotmailOUT.com (Cristiano Sadun) wrote (abridged):
> Let's see the impact regarding the cost/benefits discussion. The total
> cost of such error [...]

The point of the earlier post wasn't that these type errors are expensive
to fix, but that they are not real errors. The program is still correct
despite them. So when someone thinks, "The compiler found 10 type errors
today - it's really helping", some fraction of those errors were spurious
and the help illusory.

I don't know what fraction. It'd be interesting to put numbers on it. In
C++ (which is what I get paid to use daily) I'd guess:

(1) 50% are typos which would be found by the static checks of a good
Smalltalk. For example, mis-typing a method name like "psuh" for "push",
which Smalltalk catches at compile-time first because "psuh" is not an
English word and second because there is no method called "psuh" anywhere
in the image.

(2) 30% are trivial semantic errors which would be caught by the most
basic testing. For example, sending #push to an object that doesn't
implement it. Often this is due to attempting to compile code known to be
incomplete.
  
(3) 20% are spurious errors produced by the type system, eg const
correctness. Fewer if I anticipate and write 2 versions of methods up
front.

The vast majority of other errors are found during testing even with a
static type system. Sometimes the type checks will reveal a "deep" error,
but most of those would have been caught by good testing anyway.

I find thinking about this stuff is quite hard. Yesterday I had a design
which was pushed partly by the constrains of const correctness, and as a
C++ programmer I am happy with the direction it pushed me in, but although
I think a Smalltalk design would have been different I am not sure it
would have been objectively worse.

I'd be interested in other people's experience and numbers. Is there a
quantative study?

> > Some are due to granularity. For example, if I have a routine which
> > takes a stack argument and only uses push() on it [...]
>
> Hm, but how do you know that "only uses push"?

Because the code works.

> If every possible use of your object implies push(), why are the
> other methods defined in the first place in the interface?

Mainly because the Stack interface is also taken by other routines, which
do need those extra methods.

> If you were to write your version of Stack, and need only push()

I don't think you understand. I am not writing a Stack. I'm writing a
routine which I think takes a Stack as argument, but it turns out it only
use #push.

> Well, there would be some good, I agree, in being able to retroactively
> extend interfaces by altering their parent types; but this is not per
> se a limitation of static typing - only of current languages.

Absolutely. We were talking about mainstream languages like C++ and Java.
The argument against static checks is much weaker for languages with
better type systems, eg Haskell or Sather.

The quote that start this subthread was by Steven T Abell:

   Debugging a Java program involves dealing first with type
   errors, many of which are created by the fact that types
   are required,

Specifically Java.

> And in practice, if I understand you well, composition and wrapping can
> be used efficiently in most situations keeping the cost small.

If I have a routine which takes a Pushable, and want to call it with a
Stack which doesn't inherit, then yes, I can write a little subclass which
does inherit from Pushable, has a reference to a Stack as a member
variable, and forwards. In my view it's quite a lot of code and
complication, plus the runtime costs of the pointers and the extra
vtable. As I said before, the point is not the cost of fixing the error
but the misleading impression we get from having the error in the first
place.

> Hm. Undoubtely so, but it seems a bit academic: how much is the
> possiblity that you can exchange something so simple as an int to
> something so structured as an object without any change in the client
> code? Without even checking the code for any change?

If it doesn't work, the unit tests will detect the problem. But anyway,
it's a hypothesis of the example that it does work.

The example I had in mind was where the thing was just used for its
identity - anything supporting assignment and equality tests would be
likely to work. As it happened, I had another example at my work
yesterday, where I had to update a whole lot of code just to satisfy the
type checker. I changed a bool into a 2-valued enum.

> Again, sure there is a cost. But in writing my code I see it
> outweighted by the ability of having a clear picture of all the places
> I need to change - which (if proper design in place) is pretty much
> equivalent to all the places I need to *look at* to make sure that I
> haven't forgotten any unintended consequences; the places where I have
> to retrace and reconsider the program logic because, after all, I'm
> altering the structural properties of an essential piece of machinery
> therein.

Right. You are used to expressing that information in the static type
system, as much of it as you can. With a dynamic language you need to
express it in unit tests instead.

-- Dave Harris, Nottingham, UK



Relevant Pages

  • Re: Static vs. Dynamic typing (big advantage or not)---WAS: c.programming: OOP
    ... 20% are spurious errors produced by the type system, ... I am not writing a Stack. ... We were talking about mainstream languages like C++ and Java. ...
    (comp.programming)
  • Re: PEP 3107 and stronger typing (note: probably a newbie question)
    ... languages can be totally defeated (usually ... "Definitions of type system vary, but the following one due to ... In both cases, you can totally defeat compile-time type-checking, with possibly some very unpredictable results. ... In Java, an erroneous typecast will result in a runtime error. ...
    (comp.lang.python)
  • Re: PEP 3107 and stronger typing (note: probably a newbie question)
    ... "Definitions of type system vary, but the following one due to ... C and C++ are basically untyped languages. ... Java casts can only ...
    (comp.lang.python)
  • Re: wie Array =?ISO-8859-15?Q?f=FCr_statische_Methoden?=
    ... Wenn du eine Sprache haben willst in der du nicht so viel Tippen willst, dann würde ich dir auf gar keinen Fall Java empfehlen;) ... Das würde die Sache relativ kompakt machen, weil du keine Methodennamen brauchst und das switch gleich mitschreibst. ... Ich hab mal mit virtuellen Methoden auf einem Microkontroller experimentiert und bin zu dem Schluss gekommen: "Wenn ich virtuelle Methoden möchte dann muss ich damit leben das diese langsamer sind, selbst wenn ich das ganze in Assembler mache." ... dann brauchst du Platz auf dem Stack... ...
    (de.comp.lang.java)
  • Re: C Expression Parsing in Forth?
    ... I've worked with enough different languages and methodologies over the years to know that *all* worthwhile programming is factoring, and that is completely independent of language. ... Any modern programmer who wants to remain relevant needs to understand the complete spectrum of factoring, not just low-level factoring in Forth, and not just the higher-level factorings the refactoring community has come up with. ... I do agree that the kind of factoring that happens in Forth is greatly facilitated by unnamed items on a stack. ...
    (comp.lang.forth)