One, the Monty Hall problem. You either get it or you will die on a hill of misunderstanding. I've never seen anyone's mind be changed (I had to change my own mind). Statistics are really fucking hard.
Two, that the differences between the Java Language Spec and the Java Virtual Machine spec mean that Java is not quite as statically, strongly typed as you think. There is code that you cannot (re-)compile that runs just fine, for some useful definitions of 'fine'.
To support lazy loading of classes, and reduce inter-version dependency hell, the first invocation of every function is dynamically dispatched, and the result is memoized. It's not Duck Typing, but it isn't link-time resolution either. It's sort of a Schroedinger's Cat situation. Until you open the box it could be anything. The first Generics implementations and later generations of code obfuscators (ab)used the hell out of this. In fact I don't think Pizza (Java 1.1 era generics prototype) worked without it, and some languages-on-the-JVM may have been intractably slow.
[1]: http://wouter.coekaerts.be/2018/java-type-system-broken
>>> "foo" + 3.141
TypeError: can only concatenate str (not "float") to str
>>> object() + 3.141
TypeError: unsupported operand type(s) for +: 'object' and 'float'
Weakly typed: > "foo" + 3.141
"foo3.141"
> Object() + 3.141
"[object Object]3.141"
> [] + {}
"[object Object]"
> {} + []
0 > "foo" + 3.141
"foo3.141"
How is this weakly typed when it uses type information to work?No, this is strongly typed.
https://en.wikipedia.org/wiki/Strong_and_weak_typing#Implici...
> Smalltalk, Perl, Ruby, Python, and Self are all "strongly typed" in the sense that typing errors are prevented at runtime and they do little implicit type conversion, but these languages make no use of static type checking: the compiler does not check or enforce type constraint rules. The term duck typing is now used to describe the dynamic typing paradigm used by the languages in this group.
That is quite a qualified usage.
The only feature distinguishing Python from Javascript here is that Python does less implicit type conversion (where it is reasonable v.s. where it is insane). In every other dimension it is the same.
>>> 2**100
1267650600228229401496703205376L
>>> 'x' + u'y'
u'xy'
All Pythons implicitly convert int to float and int or float to
complex: >>> 1 + .5
1.5
>>> 2 * 3j
6j
Methods like list.extend now, in recent versions of Python (since
2.1), accept arbitrary iterables rather than just lists; it's more
debatable whether this is an “implicit type conversion” or not. >>> x = [3, 4]; x.extend((5, 6)); x
[3, 4, 5, 6]Javascript:
> null.bob()
TypeError: Cannot read property 'bob' of null
> 4 >>> Symbol("four")
TypeError: Cannot convert a Symbol value to a number
> BigInt(null)
TypeError: Cannot convert null to a BigInt
> Object.create(false)
TypeError: Object prototype may only be an Object or null: false
Java: int anInteger = 10;
String s = anInteger + "Hello";