According to Wikipedia, the terms "strongly typed" and "weakly typed" do not have agreed-upon formal definitions:

there is no precise technical definition of what the terms mean and different authors disagree about the implied meaning of the terms and the relative rankings of the "strength" of the type systems of mainstream programming languages.

Wikipedia cites a 2010 blog post by Curtis Poe for this claim, but the blog post doesn't cite any sources itself, and is written in a quite opinionated way (emphasis in original):

Probably the most common way type systems are classified is "strong" or "weak." This is unfortunate, since these words have nearly no meaning at all. It is, to a limited extent, possible to compare two languages with very similar type systems, and designate one as having the stronger of those two systems. Beyond that, the words mean nothing at all.

Therefore: I give the following general definitions for strong and weak typing, at least when used as absolutes:

  • Strong typing: A type system that I like and feel comfortable with
  • Weak typing: A type system that worries me, or makes me feel uncomfortable

Given the age and informality of the source, is this claim true? What authoritative definitions are there for "strong" and "weak" typing, and is there disagreement on these terms between different authorities?

To clarify what counts as "authoritative", see Wikipedia's rules for reliable sources (also here):

If available, academic and peer-reviewed publications are usually the most reliable sources on topics such as [...] science. [...] Other reliable sources include:

  • University-level textbooks
  • Books published by respected publishing houses
  • Mainstream (non-fringe) magazines, including specialty ones

Self-published expert sources may be considered reliable when produced by an established expert on the subject matter, whose work in the relevant field has previously been published by reliable, independent publications.

Wikipedia's article does refer to some definitions from academic literature, but these seem to describe static typing and type safety, which are usually considered distinct concepts to strong typing.

  • 14
    $\begingroup$ I think there is a real difficulty with this question because the premise is true — there isn’t an established, agreed definition, so “authoritative” sources either don’t define it (because the definition would be wrong sometimes) or use a local definition that is inconsistent with others. On the other hand, people do use those terms with locally-consistent meaning. Is an answer just a survey of different publications and how they use it? $\endgroup$
    – Michael Homer
    Commented Apr 27 at 18:45
  • 6
    $\begingroup$ Well if I'm an authority then: I agree with Curtis. Is C# strongly typed? It has many features that people describe as "strong" and many features that people describe as "weak". If you mean "allows casting", say "allows casting", not "weak". If you mean "objects can describe their types" then say "objects can describe their types", not "strong". $\endgroup$ Commented Apr 27 at 20:35
  • 2
    $\begingroup$ @EricLippert Curtis's post seemed to me a bit too polemic to be an accurate reflection of how the terms would be used by experts, but if the reason they lack formal definitions is because experts don't find the terms to be useful, then perhaps I should take his post more literally. If there is evidence that experts in general avoid these terms for that reason then that would make a great answer, and perhaps convince more people to stop using them in favour of clearer descriptors. $\endgroup$
    – kaya3
    Commented Apr 27 at 20:51
  • 4
    $\begingroup$ Found What does weak static typing/strong dynamic typing mean? on the Software Engineering stack. One answer does contain It makes a "great" argument in a flamewar about asking for the meaning of strongly typed and weakly typed. $\endgroup$ Commented Apr 28 at 8:10
  • 1
    $\begingroup$ @ChesterGillon Good find; especially the quote by Benjamin Pierce. The source for that quote seems to be a Reddit comment by Mark Jason Dominus. $\endgroup$
    – kaya3
    Commented Apr 28 at 13:56

4 Answers 4


The Wikipedia article, and the blog post, are correct that these terms are not well-defined and are not useful for communicating in general, and at best can be used in a relative way within a particular context. Sometimes they refer to accessing the bit representation of a value as another type, sometimes they are about implicit type coercions, sometimes they refer to polymorphism, sometimes they refer to the presence of static types at all, sometimes they are about expressivity or dependent properties like bounds checking, and sometimes they are just a subjective impression of quality ("A type system that I like and feel comfortable with", indeed).

You will see these terms used with quietly different meanings, and you'll see those meanings explicitly disputed, sometimes both by what you might consider experts. That doesn't mean that they aren't used or can't be useful within narrow contexts where the relativity and the elements under comparison are understood and help, but it does suggest that they're not useful as freestanding terms.

I'm going to look at some uses of these terms from academic literature over time, and then highlight some conflicts that arise within it, both explicitly and implicitly.

Firstly, let's try to look for an actual definition, and then see whether that tracks with usage.

The Oxford Dictionary of Computer Science defines "strong typing" as:

A feature of some programming languages that requires the type of each data item to be declared, precludes the application of operators to inappropriate data types, and prevents the interaction of incompatible types.

It does not have a definition for "weak typing". This is probably the closest thing to an "authoritative definition" (at least, it's trying to be), but you might find points to question in there already, and many times the term is used will not be entirely consistent with it; it also depends on the meanings of several other terms, like "type".

Strongly-, weakly-, and even statically- and dynamically-typed just are not as firmly-defined as people tend to think while they're using them. To highlight this I sometimes put forward the case that "C is strongly-typed, Perl is statically-typed": both of these claims are obviously definitionally false, and yet... they seem to be true, from a certain point of view, under conventional descriptions of what those terms mean, and many definitions inadvertently include them.

A historical wart here is also that "strong typing" and "static typing" have at times been used as essentially exact synonyms; for example, see this Bertrand Meyer abstract from OOPSLA 1992, Ensuring strong typing in an object-oriented language:

Static typing, also known as strong typing, has a long and rich history in programming languages.

On the other hand, we can look to Strong typing of object-oriented languages revisited from OOPSLA/ECOOP 1990:

We regard this as a continuum where weakly typed means that the type of an expression carries little or no information. Smalltalk is an example of such a language where the type of instance variables convey very little information on what messages are legal to send to the denoted object. A perfectly strongly typed language would exclusively have expressions where its type carries all information about the denoted object. [...] Languages with a hierarchical type system and qualified references serve as a compromise since some, but not necessarily all, operations on an object can be inferred from the qualification of the reference.

So, here, typical object-oriented polymorphism is contrary to strong typing. Among users of functional languages, this is a common concept of strong typing.

Further back, Type equivalence in strongly typed languages: one more look from 1979 says:

In a strongly typed language, each value has a unique type. The key impact of this is that, starting with the knowledge of the type of each identifier and constant appearing in the program, it is possible to determine the type of every expression in the program.

This is more or less just a description of sound static typing. It may rule out polymorphism again, although the languages being discussed simply didn't have it and that probably wasn't in mind.

A direct, if handwaved, definition is given in this paper:

Type systems may be static (compile time), dynamic (run time), strong (strict), or weak (loose). The type system of C/C++ is static and weak, meaning that it is up to the programmer to prevent type errors from occurring at runtime

followed by

The C/C++ type system is intentionally weak, i.e., allowing for arbitrary pointer casting

thus definining "weak typing" as memory reinterpretation. This is also a fairly conventional meaning for strong & weak typing.

We can see discussion of the very conflict you bring up as well, such as in Assessing the ripple effect of CS1 language choice in 2000:

Some say that C++ is strongly typed but this statement should be taken only with respect to the default static typing done on calls made through base class pointers. Otherwise, C++ is weakly typed like C, full of implicit casts, the interpretation of any type as a boolean, and the treatment of all primitives as integers -- language constructs that fail to reinforce the notion of a type to a novice.

We can see that there are some pretty divergent uses of "strong" and "weak" already. If these uses are sufficiently disjoint, maybe that would be ok.

There are direct conflicts in the uses of the terms. Let's zoom in on just one language and see how it's been described. We can see identification of Python as strongly-typed:

In contrast, using strongly typed text languages (even dynamically like Python) requires the understanding of data types and the respect of languages grammar and syntax

And we can see identification of Python as not strongly-typed:

This is rather difficult to detect in Python due to the lack of strong typing, and as such, there are additional uses that are not included in the results

TensorFlow used Python’s weak typing system to construct graphs from Python functions

We can see a set of languages classified as strongly- or weakly-typed in A Large Scale Study of Programming Languages and Code Quality in GitHub, FSE 2014:

Strong Weak
C#, Java, Go, Python, Ruby, Clojure, Erlang, Haskell, Scala C, C++, Objective-C, CoffeeScript, JavaScript, Perl, PHP

Once more, Python is identified as strongly-typed. We can also find many other real-world uses that classify it in both directions, give conflicting definitions, and argue quite intensely.

You might agree or disagree with some others of those listed languages as well — and you'll see that reflected in the literature as well, including directly in On the Impact of Programming Languages on Code Quality: A Reproduction Study in TOPLAS from Emery D. Berger, Celeste Hollenbeck, Petr Maj, Olga Vitek, Jan Vitek in 2019:

The Type category is the most counter-intuitive for programming language experts as it expresses whether a language allows value of one type to be interpreted as another, e.g., due to automatic conversion. The CACM paper attempted to clarify this definition with the example of the ID type. In Objective-C, an ID variable can hold any value. If this is what the authors intend, then Python, Ruby, Clojure, and Erlang would be weak as they have similar generic types.

The CACM paper referred to changes the name of that category to "Implicit type conversion", so clarifying that as the meaning they intended by "strong/weak typing" the first time (and likely reflecting pushback in between on this very controversy over the terms!). This is one meaning of "weak typing", but as we have seen above it's not the only one.

JavaScript given there is one of the categorical examples of weak typing, used all over the place, because of its many implicit coercions. On the other hand, another conventional perspective is that weak typing is about reinterpreting a value's memory representation as another type — this is where C falls — and you definitely can't do that in JavaScript — is it strongly typed? On yet another hand, C does define some types that can't be reinterpreted that way (function pointers) so is it strongly-typed too? We are stretching the terms beyond meaning at this point, but it highlights where these handwaves don't hold up when pushed.

Even this perspective that it's the implicit coercions that make JavaScript weakly-typed isn't as particular as it seems on the surface.

  • Is every language with implicit widening conversion from float to double then weakly-typed also? Java does that, and but is typically seen as strongly-typed.
  • Is it the sheer number of type coercions? Java and C# actually have more, because they have multiple numeric types.
  • Is it accessing methods or fields from different types through the same variable? This is just dynamic typing or polymorphism, so what's the role of "weak" here?
  • Is it automatically invoking a stringifying operation during string concatenation? Many of the supposedly strongly-typed languages given above do that too.
  • Is it that typical JavaScript code tends to invoke these coercions often? That doesn't have much to do with typing and is an empirical claim about usage, rather than the design of the language.
  • Is it converting from strings back to numbers? Now we're getting somewhere specific, but we've come a long way from "is weakly-typed" and could more usefully say that directly!

On the other hand, in Perl there is no need for such a string⇒number conversion, because numbers and strings are the same type all along: is it then strongly-typed? Or perhaps all those other languages are weakly-typed too — but clearly that perspective is not universal, so we'd need to be explaining what we meant, and one wonders why we want to use these specific words for that.

Even other answers to this question pick out JavaScript as obviously without question one or the other. They give entirely contradictory rationales that let us distinguish the meanings in use, but clearly the terms then don't tell us anything themselves. We need to explain what properties we are concerned with, and then the explanation can stand on its own instead.

We can also look to Eric Lippert, a designer of C#, to comment on that language:

Well if I'm an authority then: I agree with Curtis. Is C# strongly typed? It has many features that people describe as "strong" and many features that people describe as "weak". If you mean "allows casting", say "allows casting", not "weak". If you mean "objects can describe their types" then say "objects can describe their types", not "strong".

This is highlighting where these terms are not useful on their own: it would be better to say what you actually mean about the type system, rather than bundling it up into "strong" or "weak", if you want to communicate something. Someone else will have a different meaning and a different understanding. The Python examples above highlight that it simply isn't useful to say "strong typing": you need to say what you're actually talking about, or you'll be talking past one another.

I wanted to sum up with a general high-level description of things that were suggestive of each category, but I'm not sure I can even do that. We might try to say that:

  • A strongly-typed language is one where a value can only be used as its one true type — which could still be multiple types, or perhaps it can't, and what exactly is a type in this language, anyway?, and of course I want my language be strongly-typed and perhaps I don't want yours to be (witness the arguments about Python), and—
  • A weakly-typed language is one where the bits of a value can be reinterpreted as another type — or one where they can't, but there are "too many" coercions available, or the coercions that exist are too error-prone, or the operations that give me a value of one type given a value of another type aren't the right shape, or the types that exist aren't the sorts of types I want to think of as types, or—

We can see a pattern there that "weak typing" is mostly negative framing, and I think that brings us back around to the quote from your question:

  • Strong typing: A type system that I like and feel comfortable with
  • Weak typing: A type system that worries me, or makes me feel uncomfortable

Yes, that seems about right for how people use those terms. In context, it can make sense to contrast different approaches in that way, with a particular value system as a frame of reference, but in the abstract "strong typing" and "weak typing" don't communicate much more.

  • 1
    $\begingroup$ This is an excellent answer, thank you. One thing: where you say "This is more or less just a description of sound static typing", that definition requires "each value has a unique type", where "unique" taken literally would imply that subtypes and supertypes don't exist in the language (otherwise a value of a subtype would also have the supertype as one of its types). That's much more restrictive than strong static typing (few languages have no subtypes ─ Rust is close, but references can have subtypes with different lifetimes), but I guess that definition is not intended that way. $\endgroup$
    – kaya3
    Commented Apr 28 at 0:05
  • 7
    $\begingroup$ I have seen a definition of stronger typing (i.e., a partial order on languages), where language A is considered to be more strongly typed than language B, IFF language A's type system rejects a program that language B's accepts. However, considering the psychological aspect you highlighted in your last paragraph, that means that, of course, everybody wants their favorite language to be stronger than everybody else's favorite language. The problem is, with this definition, the strongest typed language is the one whose compiler just looks like def compile(p) = throw TypeError. $\endgroup$ Commented Apr 28 at 7:12
  • 2
    $\begingroup$ @JörgWMittag actually that's a pretty good point deserving a mention in this answer if not an answer of it's own: it's a lot easier to justify a relative ordering (e.g. Haskell is more strongly typed than Javascript) than a binary classification. I don't know if that's enough to salvage terms that are otherwise fraught with peril, but there is that. $\endgroup$ Commented Apr 28 at 13:00
  • 1
    $\begingroup$ @JaredSmith That sort of relativity is through the answer, but in reality that formal test is very rarely going to be a partial order — “rejects additional program” just isn’t going to be mutually consistent other than for small extensions to one language. I don’t think that property is useful for distant languages, just a way of saying “this change to this type system makes it more restrictive”. You can easily have different programs rejected by both sides, and what then? “Stronger” is more useful, but only because you can have a shared value system and frame of reference of the original. $\endgroup$
    – Michael Homer
    Commented Apr 28 at 18:12
  • $\begingroup$ I'm noticing that we're calling C/C++'s reinterpret casting a source of "weak" typing, but then calling C# more strongly typed despite allowing something similar in unsafe context. For example Quake's inverse square root "Evil bit hack" compiles and runs in C# if it's defined as unsafe. I'm pointing this out just because I'm guessing that for many languages there are features that might not get considered in analyzing weak vs strong because they're uncommonly used. $\endgroup$ Commented Jun 12 at 13:27

I recommend Michael Homer's answer, though I would like to offer a definition of these terms I learned in university (circa 2017) that I find sensible.

Essentially, a "weakly typed" programming language is one in which there exists one or more ways, within the language's spec, to circumvent its type system and ~~cause undefined behavior~~ break code the relies on its assumptions, requiring analysis at a lower level to understand it. (EDIT: TypeScript presents an interesting caveat that forces me to generalize this definition - see below.) A "strongly typed" programming language is simply defined as having no such holes - the type system, no matter what it is, follows its stated rules.

Note that this is distinct from "static typing" vs. "dynamic typing", which are better defined. A statically typed language is one in which the types of its values can be determined at compile time, usually accompanied by an explicit requirement to declare the types of local/global variables, function arguments, and return values. In a dynamically typed language, the type information is handled internally within the variables at runtime, with the language not concerning itself with the value's type until it's necessary to do so.

JavaScript, for instance, is dynamically but strongly typed. Variable types are kept internally and there's no way to declare which ones are what (and you can end up with variables with the wrong type at runtime), but the type system has well defined rules for all eventualities - as long as no FFI code is involved, you can follow the code from the beginning, where each and every variable is instantiated, and use the language rules to know exactly what that code is going to do. Yes, you get an error if you try to call a method that doesn't exist on an object, but because the JavaScript runtime has exact rules on what happens when you look up a property that doesn't exist (getting the special value undefined) and what happens when you run the call operator on a value (such as undefined) that doesn't support it (you get a TypeError), the type system is still strong.

Contrast that with C, which is statically but weakly typed. All variables have a specific type associated with them, which you have to declare (unless you're using a variant that lets you use auto to declare a variable if its type can be exactly inferred from the incoming expression). Most expressions have specific rules for what types can be used together and when type casts occur (including implicit type casts). However, because dereferencing an invalid pointer value causes undefined behavior, and arbitrary integers can be bit-cast to pointers (including invalid ones), it is possible to circumvent C's type system - hence, C is weakly typed.

Rust is an interesting case - safe Rust (barring any design flaws) is strongly and statically typed, while unsafe Rust is weakly and statically typed. In both cases, the type system has well-defined rules (including rules with lifetimes, which are part of the value types for each variable and expression), but in unsafe Rust, some actions that break the type system and cause undefined behavior are possible, and it is up to the programmer to ensure that they are keeping the well-defined rules within the confines of the unsafe blocks.

On this note, I would not consider implicit type coercion to be an example of a weak type system, as long as the rules themselves for when this occurs are well defined. For instance, the language might go "oh, look at me! I'm going to cast this int to a float without telling you!" but as long as it defines why it thinks it's OK to cast the int to a float, and how exactly it's going to go about it, it's still well defined. Direct bit casting, as well, is not reason enough to declare a type system weak as long as 1) the values you're casting to and from have well-defined bit patterns, and 2) the value you're casting to doesn't have any invalid values (or the language at least has a well-defined rule for how to deal with these invalid values). I would not consider using silent failure values (e.g. using NaN for floating point errors, using undefined for missing a property lookup) to be indicative of a weak type system either, as long as the language has well-defined rules for when those error values appear and how those error values behave.

And this brings me to my last point: nothing about the "strength" or "weakness" of a type system, under this definition, has anything to do with what the programmer might want out of a type system. I would definitely argue that implicit casts, reckless reinterpret casting, and silent failure values are bad, but that opinion is ultimately subjective - some other programmer, at some other time, wanted those features in their language and defined rules for how they should work. Rather, the primary meaning of the strength or weakness of a type system, under this definition, is its ability for a program written under that type system to reliably undergo a security audit. Regardless of what the actual rules for the type system are, and whether you actually want to use them, if you can at least use the type system to reliably predict what a program is going to do given specific inputs (because none of the rules of the type system can be broken by other parts of the program), then it's a strong type system. A weak type system cannot reliably undergo such an audit, and programs must instead be analyzed at a lower level (i.e. debugging at the assembly code level on the target machine) to figure out what it's doing when it's not behaving properly.

ADDENDUM: Some other examples:

  • Lambda calculus is statically and strongly typed, even though it doesn't have any type declarations (and is often considered "typeless"). This is because every single value has the same type: a function that takes one argument and returns one value (each of which is also a function that takes one argument and returns one value, and so on). The only allowed operations on these values are either calling them or composing them, which makes sense for these kinds of values.
  • Python is dynamically and strongly typed for much the same reasons as JavaScript - again, as long as no FFI code is involved, you can follow the code from the beginning and determine which values are what type, even though the language does not enforce these in the syntax.
  • Assembly code is dynamically typed, in that everything is just a set of bits and is treated as a particular kind of value upon running a specific instruction. Whether or not it's strongly or weakly typed is going to depend on the system it's running on top of, as that's where most of the actual definition of the assembly code comes from (though I think it'd be fair to call assembly language weakly typed on pretty much any platform, since system calls/interrupt vectors have different types, and there's probably at least one address that leads to invalid, undefined behavior when read to or written from from an arbitrarily constructed pointer).
  • TypeScript presents an extremely interesting case: by this definition, it is actually weakly typed while JavaScript is strongly typed, paradoxically enough. This is because TypeScript, while providing incredible and flexible static type specifications with structural types/algebraic types/true top and bottom types, lets developers lie about all of this through type assertions, and must descend to a lower layer to understand the program when this happens. However, since JavaScript is strongly (although dynamically) typed, you only have to descend to that level, while a type-circumvented C program requires descending to assembly or further.
  • 3
    $\begingroup$ Welcome! The definition in your second paragraph looks like what we would normally call "memory safety" - if there is a source for this as a definition of strong typing (e.g. your professor's lecture slides) it would help to add a link. Also, your first paragraph suggests you learned more than one definition in university, but I don't see any others (though you refer to coercion as not a definition). $\endgroup$
    – kaya3
    Commented Apr 29 at 17:51
  • $\begingroup$ @kaya3 I'll see what I can find - it was forever ago. By "some definitions", I meant to imply "a definition each for strong, weak, static, and dynamic" - I'll change it to "a definition" since those definitions are linked. $\endgroup$
    – TheHans255
    Commented Apr 29 at 18:04
  • $\begingroup$ Fair enough. I think the edit makes this clearer. $\endgroup$
    – kaya3
    Commented Apr 29 at 18:15
  • $\begingroup$ Minor quibble: in JavaScript, you can create a variable, assign it a value, and then assign it another value, and the types of the two values need not be compatible. In my mind, this makes JS weakly typed, as it enforces nothing about the type of the variable. $\endgroup$
    – JakeRobb
    Commented Apr 29 at 20:19
  • $\begingroup$ @JakeRobb That's correct, and it does disqualify JS from being statically typed. I would not consider it weakly typed, however, since JavaScript has well-defined rules of how reassigning a variable with another value of a different type is supposed to work (since it looks at the type of the actual value at runtime and enforces its rules from there). It wouldn't be any different from having a Java variable of type java.lang.Object, for example. $\endgroup$
    – TheHans255
    Commented Apr 29 at 20:23

The AdaCore Strong Typing section of Ada for the C++ or Java Developer starts with (emphasis mine):

One of the main characteristics of Ada is its strong typing (i.e., relative absence of implicit type conversions). This may take some getting used to. For example, you can't divide an integer by a float. You need to perform the division operation using values of the same type, so one value must be explicitly converted to match the type of the other (in this case the more likely conversion is from integer to float). Ada is designed to guarantee that what's done by the program is what's meant by the programmer, leaving as little room for compiler interpretation as possible.

So, in the above guide AdaCore define strong typing as the relative absence of implicit type conversions.

The other answer contains the following about weak typing:

A weakly-typed language is one where the bits of a value can be reinterpreted as another type ...

The AdaCore C to Ada Translation Patterns section of Ada for the Embedded C Developer two ways in which Ada allows the bits of a value to be reinterpreted in the Overlays vs. Unchecked Conversions section reinterpretations of bit values:

  1. Overlays using an Address clause.
  2. Unchecked Conversions, by instantiating a Unchecked_Conversion generic.

So, a language described has having strong typing may have language features or standard library functions which still allow reinterpretations of bit values.

  • $\begingroup$ I'm not sure how sound "implicit type conversion" is as a rule. If I can divide an int by a float because the languages let's int / float match int / float, is that implicit type conversion? If I can divide an int by a float because the language defines int / float to do the conversion explicitly but under the hood, is that implicit type conversion? A lot of languages allow int / float without technically using implicit conversions. $\endgroup$ Commented Apr 28 at 9:15
  • $\begingroup$ @MisterMiyagi I don't know any language which defines int / float in any other way than "coerce the int to a float, then divide". In Java this is called a "widening primitive conversion", for example. It would be difficult to define it any other way, since IEEE 754 doesn't specify any binary operations on floating point numbers where the other operand is not a floating point number. $\endgroup$
    – kaya3
    Commented Apr 28 at 13:49
  • 1
    $\begingroup$ @kaya3 IEEE 754? Thousands of languages were created before it was first defined in 1985, so a huge number of languages aren't going to define it based on what IEEE 754 says. $\endgroup$
    – prosfilaes
    Commented Apr 28 at 14:58
  • $\begingroup$ @kaya3 I'm not sceptical about the int value being converted to a float value, but about that being done necessarily as an implicit type conversion (via coercion as in your example). Any language that allows for explicit type conversions and operators can trivially define this via those mechanisms, without the type system doing anything implicitly. $\endgroup$ Commented Apr 28 at 15:12
  • $\begingroup$ @MisterMiyagi In what sense is the conversion in int / float not implicit, if it is not written explicitly like ((float) x) / y? It doesn't matter how that is implemented, whether by operator overloading or otherwise. $\endgroup$
    – kaya3
    Commented Apr 28 at 15:18

For me, strong and weak typing imply that the compiler, runtime, or anything else (other than the code you write) is enforcing something about the types of various pieces of data. Variables, arguments, return values, etc (which I will refer to as "variables" henceforth).

The "something" part is indeed arbitrary, but when we constrain the domain to data types, to my mind it really only leaves one thing that could be enforced. Dynamic typing, duck typing, type inference, type coercion, and other features of a type system are not important, because they are not about enforcement.

A strongly typed language enforces that when a variable is declared, it is assigned a type (explicitly or implicitly), and for the duration of the variable's lifecycle, it will continue to have that type and only that type. A weakly typed language doesn't do this.

Let's pick on JavaScript as an example of a weakly typed language. The following is entirely reasonable:

var a = 123; // a has type number
a = "123"; // now a has type string.

And then let's contrast with JavaScript's strongly typed (IMO) cousin, TypeScript, in which the same code is not permitted.

var a = 123; // a has type number
a = "123"; // doesn't compile

JavaScript's type-related weakness goes beyond this enforcement with type coercion, but that's entirely separate from being weakly typed (i.e., you could have a language with one but not the other). That said, type coercion and weak typing go hand-in-hand in several ways, not least of which is the fact that they both allow subtle bugs to sneak into code way too easily for my personal taste. 🙂

There are plenty more examples of weakly typed languages (Shell comes to mind). There's nothing wrong with them, but personally, I try not to use them in complex and/or production systems if I have a choice.

EDIT: apologies; I missed that the question is looking for authoritative answers. I looked to see if I can find any authoritative sources that share my opinion. What I found was just a single other use of "strong" and "weak" in a programming context which feels consistent:

  1. A weak reference, in languages/runtimes with automatic memory management, is one in whose existence does not protect the value from being freed or garbage collected. You could rephrase my claim as "in a strongly typed language, the compiler or runtime protects the variable from being assigned a type-incompatible value." Therefore: "strong" implies some kind of protection, and "weak" implies a lack of said protection.
  2. Nope, #1 is all I've got. leaves quietly
  • $\begingroup$ Welcome! Note that this question is asking for "authoritative" definitions ─ do you have a reference to show that this definition is used by researchers, language designers, etc.? $\endgroup$
    – kaya3
    Commented Apr 29 at 20:44
  • $\begingroup$ Ah, sorry, I missed that part of the question. I don't, but I'll look around and see if I can find anyone authoritative who agrees with me. 😉 $\endgroup$
    – JakeRobb
    Commented Apr 29 at 20:50
  • $\begingroup$ I've edited with a very weak hint of authoritative support for my opinion. 😅 $\endgroup$
    – JakeRobb
    Commented Apr 29 at 21:06
  • $\begingroup$ "A strongly typed language enforces that when a variable is declared, variable is assigned a type (explicitly or implicitly), and for the duration of the variable's lifecycle, it will continue to have that type and only that type. A weakly typed language doesn't do this." JavaScript enforces this property on values. If you have two variables that name the same array, then you can make one or the other name an integer instead, but you can't make them simultaneously name an integer by transforming the array into an integer. $\endgroup$ Commented Apr 30 at 17:18
  • $\begingroup$ @KarlKnechtel I don't follow. What does it mean for two variables to "name the same array"? $\endgroup$
    – JakeRobb
    Commented Apr 30 at 17:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .