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.
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
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
``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.''
Erlang isn't statically typed, yet you can't do what the OP shows.
"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.
"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.)
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.
The only languages with "weaker" typing are languages with no concept of types at all.
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.
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)`.
>>> unicode(u"straße", 'utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: decoding Unicode is not supported
Things which silently throw away precision, change values and semantics in dangerous ways should never happen automatically.
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
This article about CL but it's applicable to Python as well: