As others have noted, the terms “strongly typed” and “weakly typed” have so many different meanings that there’s no single answer to your question. However, since you specifically mentioned Perl in your question, let me try to explain in what sense Perl is weakly typed.
The point is that, in Perl, there is no such thing as an “integer variable”, a “float variable”, a “string variable” or a “boolean variable”. In fact, as far as the user can (usually) tell, there aren’t even integer, float, string or boolean values: all you have are “scalars”, which are all of these things at the same time. So you can, for example, write:
$foo = "123" + "456"; # $foo = 579 $bar = substr($foo, 2, 1); # $bar = 9 $bar .= " lives"; # $bar = "9 lives" $foo -= $bar; # $foo = 579 - 9 = 570
Of course, as you correctly note, all of this can be seen as just type coercion. But the point is that, in Perl, types are always coerced. In fact, it’s quite hard for a user to tell what the internal “type” of a variable might be: at line 2 in my example above, asking whether the value of
$bar is the string
"9" or the number
9 is pretty much meaningless, since, as far as Perl is concerned, those are the same thing. Indeed, it’s even possible for a Perl scalar to internally have both a string and a numeric value at the same time, as is e.g. the case for
$foo after line 2 above.
The flip side of all this is that, since Perl variables are untyped (or, rather, don’t expose their internal type to the user), operators cannot be overloaded to do different things for different types of arguments; you can’t just say “this operator will do X for numbers and Y for strings”, because the operator can’t (won’t) tell which kind of values its arguments are.
Thus, for example, Perl has and needs both a numeric addition operator (
+) and a string concatenation operator (
.): as you saw above, it’s perfectly fine to add strings (
"1" + "2" == "3") or to concatenate numbers (
1 . 2 == 12). Similarly, the numeric comparison operators
<=> compare the numeric values of their arguments, while the string comparison operators
cmp compare them lexicographically as strings. So
2 < 10, but
2 gt 10 (but
"02" lt 10, while
(The fly in the ointment here is that, for historical reasons, Perl 5 does have a few corner cases, like the bitwise logical operators, whose behavior depends on the internal representation of their arguments. Those are generally considered an annoying design flaw, since the internal representation can change for surprising reasons, and so predicting just what those operators do in a given situation can be tricky.)
All that said, one could argue that Perl does have strong types; they’re just not the kind of types you might expect. Specifically, in addition to the “scalar” type discussed above, Perl also has two structured types: “array” and “hash”. Those are very distinct from scalars, to the point where Perl variables have different sigils indicating their type (
$ for scalars,
@ for arrays,
% for hashes)1. There are coercion rules between these types, so you can write e.g.
%foo = @bar, but many of them are quite lossy: for example,
$foo = @bar assigns the length of the array
$foo, not its contents. (Also, there are a few other strange types, like typeglobs and I/O handles, that you don’t often see exposed.)
Also, a slight chink in this nice design is the existence of reference types, which are a special kind of scalars (and which can be distinguished from normal scalars, using the
ref operator). It’s possible to use references as normal scalars, but their string/numeric values are not particularly useful, and they tend to lose their special reference-ness if you modify them using normal scalar operations. Also, any Perl variable2 can be
blessed to a class, turning it into an object of that class; the OO class system in Perl is somewhat orthogonal to the primitive type (or typelessness) system described above, although it’s also “weak” in the sense of following the duck typing paradigm. The general opinion is that, if you find yourself checking the class of an object in Perl, you’re doing something wrong.
1 Actually, the sigil denotes the type of the value being accessed, so that e.g. the first scalar in the array
@foo is denoted
$foo. See perlfaq4 for more details.
2 Objects in Perl are (normally) accessed through references to them, but what actually gets
blessed is the (possibly anonymous) variable the reference points to. However, the blessing is indeed a property of the variable, not of its value, so e.g. that assigning the actual blessed variable to another one just gives you a shallow, unblessed copy of it. See perlobj for more details.