[Python-ideas] [Wild Idea] Static Ducks

Stephen J. Turnbull stephen at xemacs.org
Wed Sep 23 06:39:38 CEST 2009

Steven D'Aprano writes:

 > I agree that treating weak/strong as a binary state is an 
 > over-simplification, but a weak/strong axis is perfectly reasonable. 
 > Count the number of possible mixed-type operations permitted by the 
 > language (for simplicity, limit it to built-in or fundamental types).
 > What percentage of them succeed without explicit casts or conversions?
 > If that percentage is 0%, then the language is entirely strong. If it is 
 > 100%, then the language is entirely weak. In practice, languages will 
 > likely fall somewhere in the middle rather at the ends. This is an 
 > objective test for degree of type strength.

Sure, but I think Masklinn's point here is that it's a partial order.
I might very well consider a language with a D'Aprano index of 10%
more strongly typed than one with an index of 5% (eg, if the 10% are
all numeric coercions based on embeddings, while the 5% is various

That said, I think Masklinn is being unreasonable.  Although there
surely are more folks like him who refuse to accept any notion of
"strength of typing", I think most people would be in rough agreement
as to which direction the axis points.

 > > > Automatically converting ints to floats is mathematically
 > > > reasonable, because we consider e.g. 3 and 3.0 to be the same
 > > > number.

I don't think we do consider them to be the *same*; substitutability
is one-way.  Yes, 3 can be used in place of 3.0 because the integers
can be embedded in the reals, but in general not vice versa.  We
prefer counters (eg in loops) to *not* automatically convert floats to
ints.  Supplying a float where an int is expected is generally a logic
error, not a notational convenience.

This notational convenience is very great, however.  It's not just a
matter of eliding the ".0" from "3.0"; it's also used in contexts like

    # enumerate the labels on the y-axis
    y-labels = list(0.50 + 0.05*i for i in range(10))

and in the cake-division problem below.  (A hairy mathematician would
point out that this can be justified as a notation for repeated
addition rather than coercion to float for multiplication, but I'm too
bald to bother, besides being an economist anyway.)  Note that you
cannot write "list(range(0.5,1.0,0.05))" to compute y-labels, though
that spelling seems very plausible to me.

I would argue that a language that coerces integer to float (or the
singleton 'nil' to list, to give another common example) is only
slightly more weakly typed than one that doesn't, because of the
embedding.  But one that coerces float to integer is much more weakly
typed than one that doesn't, because there is no embedding.

 > > Do we? Given 3/2 and 3.0/2 don't necessarily give the same answer
 > > (some languages don't even consider the first operation valid), I'm
 > > not sure we do.
 > Ask a mathematician, and he'll say that they are the same. The 
 > underlying concept of number treats 3 and 3.0 as the same thing (until 
 > you get to some extremely hairy mathematics,

No, even naive non-mathematicians may tell you they're different.  If
you ask any reasonably competent (but non-programmer) sixth grader,
they will tell you that 3/2 is "1 with a remainder of 1" (and we have
to play scissor-paper-stone to decide who gets the last piece of hard
candy), while 3.0/2 is "1.5" (and we split the third piece of cake in
half with a fork).

More information about the Python-ideas mailing list