This is a comparison of the features of the type systems and type checking of multiple programming languages.

Brief definitions A nominal type system means that the language decides whether types are compatible and/or equivalent based on explicit declarations and names. A structural type system means that the language decides whether types are compatible and/or equivalent based on the definition and characteristics of the types. Type checking determines whether and when types are verified. Static checking means that type errors are reported based on a program's text (source code). Dynamic checking means that type errors are reported based on a program's dynamic (run-time) behavior.

Language Type safety Type expression Type compatibility and equivalence Type checking A+ strong dynamic ActionScript 3.0 strong static ABC strong ABAP strong nominal static Ada strongUnsafe operations are well isolated by a "Unchecked_" prefix. explicit nominal static Agda strong nominal static Aldor weak static Alef strong static ALGOL 58 strong explicit static ALGOL 60 strong explicit static ALGOL 68 strong explicit structural static & tagged unions ALGOL W strong static Alice strong static Alma-0 static AmbientTalk strong dynamic AMOS BASIC static AngelScript strong static APL strong dynamic AppleScript weak dynamic Arc dynamicAssembly AutoHotkey typeless AutoLISP dynamic Ateji PX strong explicit nominal static AWK weak implicit dynamic B typeless Ballerina strong structural static Bash BASIC strong explicit nominal static BCPL typeless BeanShell strong nominal dynamic BLISS typeless Boo strong Bro strong nominal static C weak explicit nominal static C-- weak static C++ (ISO/IEC 14882) strong nominal C* weak explicit static C# strong nominal C shell Caml strong static Cecil Clean strong implicit static Ceylon strong static Chapel static CHILL strong static ChucK strong Cilk weak explicit static Claire strong Clean strong static and dynamic Clojure strong dynamic CLU strong COBOL strong explicit nominal static Cobra strong CoffeeScript implicit dynamic ColdFusion (CFML) strong implicit dynamic COMAL strong Common Lisp strong structural for implicit typing, nominal for explicit typing dynamic, some static checking(depending on implementation) Component Pascal strong static Cool strong explicit static CORAL strong static Crystal structural static Cuneiform explicit static Curl strong nominal Curry strong static Cython strong nominal (extension types) and structural (Python) D weakIt is almost safe, unsafe features are not commonly used. explicit nominal static Dart strong gradual typing nominal Dylan strong dynamic Eiffel strong nominal static Elixir strong implicit dynamic Erlang strong implicit dynamic Euphoria strong explicit, implicit with objects nominal static, dynamic with objects F# strong implicit nominal static Forth typeless Fortran strong explicitOptionally, typing can be explicitly implied by the first letter of the identifier (known as implicit typing within the Fortran community). nominal static Gambas strong explicit nominal GLBasic strong explicit. Non-explicit declarations available through project options nominal static Gleam strong nominal static GoThe Go Programming Language Specification strong structural static Gosu strong nominal (subclassing) and structural static Groovy strong Harbour strong dynamic Haskell strong nominal static Haxe strong nominal (subclassing) and structural Io strong implicit dynamic icon strong implicit dynamic ISLISP strong dynamic J strong dynamic Java strongSheng Liang, Gilad Bracha. Dynamic class loading in the Java virtual machine. Volume 33, Issue 10 of ACM SIGPLAN Notices, October 1998. explicit nominal static JavaScript weak implicit dynamic Julia strong structural for implicit typing, nominal for explicit typing dynamic Joy strong dynamic Kotlin strong nominal static LabVIEW strong Lua strong implicit dynamic Maple strong dynamic Mercury strong static Mathematica strong dynamic MATLAB M-code strong dynamic Modula-2 weak explicit nominal static Modula-3 weak explicit structural static MUMPS (M) typeless Neko dynamic Nemerle strong implicit nominal static NetLogo strong implicit dynamic NetRexx strong newLisp implicit dynamic NEWP strong static Newspeak dynamic NewtonScript dynamic Nial dynamic Nim strong static Nickle strong Nu dynamic Oberon strong explicit nominal Objective-C weak explicit nominal OCaml strong nominal for records, structural for objects static Object Pascal strong explicit nominal static Opa strong structural static Oxygene weak implicit static Oz-Mozart strong implicit structural dynamic Pascal weak explicit nominal static Perl 5 implicit dynamic PHP weak nominal dynamic Plus strong explicit structural Prolog dynamic Pure strong dynamic PureScript strong nominal static Python strong nominal dynamic R implicit dynamic Raku REBOL strong implicit dynamic Rexx typeless , implicit wrt numbers static+dynamic wrt numbers RPG weak static Ruby strong implicit dynamic Rust strong mostly nominal static S dynamic S-Lang strong implicit dynamic Scala strong nominal (subclassing) and structural static Scheme strong implicit dynamic (latent) Seed7 strong explicit nominal static Simula strong Smalltalk strong implicit dynamic Swift strong nominal (subclassing) and structural static Standard ML strong structural static Tcl dynamic TypeScript strong optional structural static Unicon strong implicit dynamic Visual Basic strong nominal static weak explicit static Visual Prolog strong nominal static Wolfram Language strong dynamic Windows PowerShell strong implicit dynamic XL strong nominal static Xojo strong explicit nominal static XPath/XQuery strong nominal Language Type safety Type expression Type compatibility and equivalence Type checking

Notes

References