Seeking Clarification on Apparent Contradictions Regarding Weakly Typed Languages

Seeking clarification on apparent contradictions regarding weakly typed languages

UPDATE: This question was the subject of my blog on the 15th of October, 2012. Thanks for the great question!


What does it really mean for a language to be "weakly typed"?

It means "this language uses a type system that I find distasteful". A "strongly typed" language by contrast is a language with a type system that I find pleasant.

The terms are essentially meaningless and you should avoid them. Wikipedia lists eleven different meanings for "strongly typed", several of which are contradictory. This indicates that the odds of confusion being created are high in any conversation involving the term "strongly typed" or "weakly typed".

All that you can really say with any certainty is that a "strongly typed" language under discussion has some additional restriction in the type system, either at runtime or compile time, that a "weakly typed" language under discussion lacks. What that restriction might be cannot be determined without further context.

Instead of using "strongly typed" and "weakly typed", you should describe in detail what kind of type safety you mean. For example, C# is a statically typed language and a type safe language and a memory safe language, for the most part. C# allows all three of those forms of "strong" typing to be violated. The cast operator violates static typing; it says to the compiler "I know more about the runtime type of this expression than you do". If the developer is wrong, then the runtime will throw an exception in order to protect type safety. If the developer wishes to break type safety or memory safety, they can do so by turning off the type safety system by making an "unsafe" block. In an unsafe block you can use pointer magic to treat an int as a float (violating type safety) or to write to memory you do not own. (Violating memory safety.)

C# imposes type restrictions that are checked at both compile-time and at runtime, thereby making it a "strongly typed" language compared to languages that do less compile-time checking or less runtime checking. C# also allows you to in special circumstances do an end-run around those restrictions, making it a "weakly typed" language compared with languages which do not allow you to do such an end-run.

Which is it really? It is impossible to say; it depends on the point of view of the speaker and their attitude towards the various language features.

Java being strongly typed

In a Weakly Typed language conversion between unrelated data types is implicit.

For e.g JavaScript is a Weakly Typed language :

var x = 22;
var y = x + "example";
console.log(y); # prints 22example as an instance of String object
# Here the value of x got converted to string without any explicit conversion by the programmer.

A Strongly Typed language is exact opposite. You can do type conversion in Strongly Typed languages, but they are not implicit. You have to do them explicitly.

For e.g Java is a Strongly Typed language :

int x = 2;
Long y = x; # Will throw compilation error
# However you can do something like below example
Long y = new Long(x);
# There are other ways to do type conversion in java for different data types, but they are not implicit, you gotta do them explicitly.

I hope this answers your question.

Is weak typing not necessary anymore?

Weak typing is primarily useful in low-level programming. A function to read an integer or string off a disk, for example, will have to take a sequence of bytes and come up with an integer or string. That's much harder to do with strong typing.

Annotations in TestNG are strongly typed. What does it mean?

What the book is most likely trying to do, is distinguish between the following two approaches:

  1. Use method name conventions to identify test methods

    This was the case in (for example) JUnit 3, where the name of the test method would be prefixed with test (e.g. testSomeLogic()). This allowed the test library to distinguish between those methods that were actually considered tests, and other setup or utility methods.

  2. Use annotations to identify test methods

    In TestNG and later versions of JUnit, the approach has been to prefer annotating the methods with specific test-related annotations (e.g. @Test). The goal here is the same, it allows the test library to correctly identify test and other test-related methods.

The benefit of using annotations is that they are actual Java types and will be checked by the compiler. Mistakenly using the annotation @Tset will result in a compilation error, alerting the user to the problem.

Spelling mistakes in method names can not be detected by the compiler. A method tsetSomeLogic() will just not be executed, and the user will be left unaware.

Is Python a weakly typed language as variables can switch types?

Your example demonstrates dynamic typing, not weak typing. Dynamic typing generally means that the type of data an object can store is mutable; any target may hold a binding to any kind of object. Contrast that with, say, C#, which is statically typed [*].

int i = 5; // Okay.
i = "5"; // Illegal! i can only hold integers.

Strong typing means that once assigned a value of a particular kind, objects obey strict rules about how they can interact with other objects of various types. Weak typing means that such rules are more relaxed. This doesn't mean that strongly typed languages are necessarily superior in any way; it's just a language design choice.

Python is considered strongly typed because objects have a distinct notion of what they type they are. Incompatible operations between objects cause errors:

>>> 1 + 1          # Add two integers.
2
>>> "1" + "1" # Concatenate two strings.
'11'
>>> 1 + int("1") # Add two integers.
2
>>> "1" + str(1) # Concatenate two strings.
'11'
>>> 1 + "1" # Undefined! Adding integers and strings is meaningless.
Traceback (most recent call last):
File "", line 5, in ?
TypeError: unsupported operand type(s) for +: 'int' and 'str'

But in PHP, the rules are much more relaxed about what is acceptable. Thus it is considered more weakly typed than some other languages.

$x = 1 + "1"; // x is 2

[*] Technically, as of C# 4, C# is statically typed but with opt-in dynamic typing on a per-binding basis, thanks to the dynamic keyword. A lot of languages these days are adding dynamic capabilities and blurring the lines, so it's becoming increasingly harder to say that "language X is dynamic" and "language Y is static". It's much more of a sliding scale or a spectrum than it is a binary property.

Is there a statically weak typed language?

The definition of strongly and weakly typed is not well defined, especially in the context of rating just one language. It is a commonly used axis on which to compare languages, and in that context strong and weak typing gain more meaning but it is important to understand that there is no rigorous definition like static and dynamic. What makes a type system weak or strong comes down to a the ways in which the programmer is able to create type errors.

Unchecked explicit casting

A lot of people would consider C weakly typed because a programmer is allowed to cast types. I can add a pointer to a character if I just tell C that they are both integers.

int main () {
char c = 'a';
void *p;
(int)c + (int)p;
}

In Haskell, however, I can explicitly cast from on type to another, but only certain types will work.

ord('c') + 10
fromIntegral (2::Int) + 4.13

Java has static type casting as well which allows the programmer to, for example, downcast objects. This makes the static type system not sound. But Java has dynamic type checking for just this reason. Yes, Java has dynamic and static type checking. For this reason, however, I think many people would consider Java to be strongly typed.

Automatic casting

Perl and Javascript will take strings and consider them to be numbers if they look enough like a number and automatically make it work.

'2 is my favorite number' + 413 == 415 # in Perl

If you want to a string to a number in, say, Scheme you have to explicitly convert using a function that does a check and raises exception if they string is not a number.

(= (+ (string->number '2') 413) 415) ; In Scheme

For this reason a lot of people would consider Scheme strongly typed.

No types at all

In some languages there aren't any types. The untyped Lambda Calculus is one such example. This is clearly not strongly typed. Everything is a function. I can have numbers using Church Numerals or pairs or strings or whatever using various encodings but values only mean what I agree they mean and there is certainly overlap.

Comparison

Like I said, the terms are not well defined but they are a little more useful when used in a relative manner. For example I could make a good claim that OCaml is more strongly typed than Java, because Java allows for explicit static down casting whereas OCaml does not.

Conclusion

The terms aren't rigorous but they are useful. To answer your original question, in my opinion, C/C++ are static and weakly typed, so they fit the description.

Are weak languages also called untyped languages?

The "weak" / "strong" typing thing has no universal definition. It depends on the author. Sometimes "weakly typed" means the language allows implicit type conversions, but that's a bit vague and generally "weakly typed" just means the author doesn't like the language. (For example, Python implicitly converts between integers and floating point numbers, yet people often call it "strongly typed".)

From a static typing / type theory point of view, all "dynamically typed" languages are untyped because they lack a real (static) type system.

I don't know what you mean by "loosely typed" or "static language".



Related Topics



Leave a reply



Submit