> My experience, in practice, is that when people say "strong" and "weak", I do indeed find that as cdsmith says, "strong" mostly corresponds to "it makes me comfortable".
But even people who are very comfortable in C, do not say that C is strongly-typed.
In my experience, people agree on which languages are strongly- or weakly-typed, and that can be used to reverse-engineer the definition, based on the properties those languages differ on. Assembly, C, and PHP are all weakly-typed, at the very least, and their proponents agree with this. They don't agree on why they are weakly-typed, simply that they are.
The original definition I ever heard for weak-typing, back when C and Assembler were the only things that had it, was "a weakly-typed language allows you to take the raw, in-memory representation of data of type A, and perform operations on it as if it were data of type B that had an equal raw, in-memory representation." The most famous example of this is Quake's fast invsqrt(), where the bytes making up a float have int operations applied to them, as if they were bytes making up an int.
Of course, PHP doesn't have this capability, but we still call it weakly-typed. So the definition must have moved on from its previous strict form. What does PHP allow you to do, that gets it called weakly-typed? This:
echo "(" + 5 + ")"; # prints "5"!
PHP, here, is taking the Strings "(" and ")" and interpreting them as numbers for the purposes of the addition operator. However, the strings "(" and ")" are not
valid numbers—but PHP is fine with this, and uses the default numeric value of 0 to represent this invalidity.
The similarity with the original definition, is that the data is transformed from one type to another, not implicitly, and not that the raw representation of the data is used, but rather without a guarantee that the datatypes have the same capacity for informational entropy. In other words, casting "(" to a number silently loses data, just as storing an int in a char variable in C silently loses data. This fact seems to be universal to all languages that get called "weakly-typed", and non-existent in any language that has never had that epithet applied to it.
It has nothing to do, notice, with whether a language will implicitly cast values—as long as all implicit conversions happen upward to types that have "room" for all the information in the original representation (char -> int, int -> String, int -> float) the language is still strongly-typed. And notice that the datatype itself being lost in a typecast (String -> Object) cannot be a reason to call a language weakly-typed because, in an interface-like cast like this, all the data is still retained, and its original form can be reclaimed simply by casting it back (Object -> String).