
Is Python strongly typed? - avinassh
http://stackoverflow.com/questions/11328920/is-python-strongly-typed
======
cousin_it
Strong typing (absence of implicit conversions) is a spectrum, with some
aspects being more important than others.

1) Do you allow 1 + 1.5? Most languages say yes, even very disciplined ones
like Haskell. Very few languages say no, like Ocaml.

2) Do you allow "hello" \+ 1? Some languages say yes, like Java. Some
languages say no, like Python. It doesn't seem very important either way.

3) Do you allow implicit conversion between pointers and integers? Most
languages say no. Very few languages say yes, like C or assembly.

When people ask "is Python strongly typed?", they usually mean either "is
Python statically typed?" (no, because a TV with a single color is not a color
TV) or "is Python memory-safe?" (yes, unless you make a special effort to
break it). Beyond these two questions, there's very little to learn from the
fact that Python happens to disallow "hello" \+ 1.

~~~
masklinn
> 1) Do you allow 1 + 1.5? Most languages say yes, even very disciplined ones
> like Haskell.

That's not really because of an implicit conversion. Integral literals are
typed as `Num a` and floating literals as `Fractional a`, since `+ :: Num a =>
a -> a -> a` both operands must be of the same type, so `1` becomes a
`Fractional a :: a` and voilà, the expression is correctly typed as
`Fractional a :: a`.

Force `1` to a concrete integral type and you'll get a type error because
there is no `Fractional Int` instance which would satisfy `(+)`:

    
    
        Prelude> (1 :: Int) + 1.5
    
        <interactive>:28:14:
            No instance for (Fractional Int)
              arising from the literal `1.5'
            Possible fix: add an instance declaration for (Fractional Int)
            In the second argument of `(+)', namely `1.5'
            In the expression: (1 :: Int) + 1.5
            In an equation for `it': it = (1 :: Int) + 1.5

~~~
cousin_it
Yeah, I know that the literal 1 has type Num a => a. Actually I suspect that's
a bit of a flaw in Haskell. All the interesting things we can do with 1 as a
literal (like adding it to 1.5) are also things we could do with the length of
a one-element list, but in Haskell these two 1's are not interchangeable.
Also, defaulting rules seem to be a wart that's necessary only because of
overloaded literals. Maybe the literal 1 could have type Integer, and 1 + 1.5
could work through some other kind of typeclass magic?

------
amelius
The intended question is: is python statically typed? Strictly speaking, it
depends on what you call a type. If you think of all possible values
(integers, strings etc.) as being of a single type, then python is statically
typed. However, most people wouldn't think of the values that way.

~~~
rusabd
yes

[https://en.wikipedia.org/wiki/Lambda_calculus#Typed_lambda_c...](https://en.wikipedia.org/wiki/Lambda_calculus#Typed_lambda_calculus)
``From a certain point of view, typed lambda calculi can be seen as
refinements of the untyped lambda calculus but from another point of view,
they can also be considered the more fundamental theory and untyped lambda
calculus a special case with only one type.''

~~~
unfamiliar
Where should I start reading to understand lambda calculus?

~~~
rusabd
I like this one
[http://worrydream.com/AlligatorEggs/](http://worrydream.com/AlligatorEggs/)

------
afandian
Nothing controversial (or particularly noteworthy) here.

~~~
svisser
It might be for some as it's a common misconception that Python does not have
strong typing.

~~~
masklinn
The "misconception" probably comes from "strong typing" being less an
objective concept and more an attempt to weaselly state language preferences.

~~~
duaneb
Well strong vs weak typing is both orthoganal to and predates most of the
discussion of static vs dynamic typing. You have to deal with conversions no
matter what.

~~~
masklinn
> Well strong vs weak typing is orthoganal to the discussion of static vs
> dynamic typing.

"strong vs weak" can't be orthogonal to anything because it's meaningless and
nonsensical. That's like saying NaN is lower than 5.

> Well strong vs weak typing is predates most of the discussion of static vs
> dynamic typing.

[citation required]

~~~
duaneb
I'm not sure what there is to be confused about.

"weak" types mean they may elide into other types implicitly. "strong" types
mean that the value will always be interpreted as one (set of) type(s).
(really just one type, but that type may be a subtype, so it gets confusing.)

------
reagency
Maybe the names are poor.

Strong/Weak typing refers to Conversion Typing. Or Type Malleability. It is
about the implicit conversions or transitions between types.

Static/Dynamic refers to Variable Typing (or Identifier Typing). It refers to
the type of an expression.

~~~
pluma
The problem is that many use Strong/Static and Weak/Dynamic as synonyms.
Dynamically typed languages happen to often be weakly typed and statically
typed languages happen to often be strongly typed. This is why you get people
debating whether Python is "strong or dynamic" although that's a false
dichotomy.

------
bufordsharkley
I recommend this article going into good depth on how Python's name and
binding model functions:

[https://www.jeffknupp.com/blog/2013/02/14/drastically-
improv...](https://www.jeffknupp.com/blog/2013/02/14/drastically-improve-your-
python-understanding-pythons-execution-model/)

------
devit
In both (classic) Python and JavaScript, there is no static typing and you can
change the type of existing objects, access all their fields, and add/remove
methods and field any time.

The only languages with "weaker" typing are languages with no concept of types
at all.

~~~
legulere
Strong/weak typing generally refers to types being implicitly converted. It's
a almost completely orthogonal concept from static/dynamic typing. For
instance C has several implicit integer width conversions. Javascript, PHP and
Ruby are often used as examples for weak typing.

------
epx
Python 2 was broken when Unicode strings were allowed weak conversion from/to
regular strings.

~~~
masklinn
So Java is "broken" because it performs "weak conversion" (whatever the hell
that means) between integers and floats, or anything and strings? And Scala
would be even more "broken" because _developers_ can define "weak conversion"?

~~~
anon4
In the reply below "str" and "unicode" refer to the python types of those
names, not to generic "string" and "unicode".

No, in this case it was broken because things suddenly started working in
weird ways, because type conversions between str and unicode were taking place
when you weren't expecting it. So it's "broken practically" and not "broken
philosophically". You could call X.encode('utf-8') expecting to get the utf-8
byte representation of a string, only to be told "character \xf8 at position
whatever cannot be handled by ASCII decoder", because X is a str containing
weird bytes and not an unicode, so when you ask to have it encoded, it is
first silently decoded to unicode using the default encoding - ASCII in this
case. You could do X + Y and get the same error because one of them happens to
be an unicode, but the other is a str which python tries to convert to
unicode.

~~~
masklinn
Your comment has very limited relation to the GP in that the issue you outline
is not the implicit conversion itself but the fact that said implicit
conversion _may_ fault and it is nigh impossible to know where that could
happen until it does.

For the record I would agree, but I'm guessing it made sense in the context
surrounding the introduction of "proper" unicode objects in Python 2
considering all the issues which cropped up after the Python 3 split and the
issue of correctly dispatching APIs between str and unicode.

Furthermore some of the APIs are decidedly idiotic: `unicode` can take a
string and an encoding, one could expect that if an encoding is provided it'll
try to decode str inputs but let unicode go through unmolested, and thus could
be a convenient way to ensure a possibly-str input is converted to unicode.
After all, forced conversion is already available using e.g.
`str(obj).decode(encoding)`.

Well,

    
    
        >>> unicode(u"straße", 'utf-8')
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        TypeError: decoding Unicode is not supported

------
kashif
One way to think about strong typing is that type matters when performing
operations on a variable. If the type is not as expected, a language that
complains is strongly typed (python/java) and one that isn't is weakly typed
(javascript)

Dynamically typed languages(python) are those which allow the type of a
variable to change at runtime whereas statically typed languages(java) do not
allow this once a variable is declared

------
halayli
no implicit type conversion is just one of several strongly typed properties.
type checking & safety weigh more to label a language as a strongly typed one.

------
draw_down
In a strongly typed language, you wouldn't be able to interpret 'bob' as a
number without an explicit coercion. That's as I understand it, but I also
understand that terms like "strongly typed" are not well-defined.

------
rusabd
Python is strongly typed with one type

This article about CL but it's applicable to Python as well:

[http://xach.com/naggum/articles/3284289178877169KL2065E@nagg...](http://xach.com/naggum/articles/3284289178877169KL2065E@naggum.no.html)

