Comparison of programming languages by type system

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
ActionScript 3.0 strong implicit with optional explicit typing static
Ada strong[TS 1] explicit nominal static
Aldor weak implicit static
ALGOL 58 strong explicit static
ALGOL 60 strong explicit static
ALGOL 68 strong explicit structural static & tagged unions
APL strong dynamic
AutoHotkey typeless n/a n/a n/a
Ateji PX strong explicit nominal static
Bash ‹See Tfd›? ‹See Tfd›? ‹See Tfd›? ‹See Tfd›?
BASIC strong explicit nominal static
BLISS typeless n/a n/a n/a
BeanShell strong nominal dynamic
Boo strong implicit with optional explicit typing static with optional dynamic typing
Bro strong implicit with optional explicit typing nominal static
C weak explicit nominal static
C++ (ISO/IEC 14882) weak explicit with optional implicit typing (by using auto in C++11) nominal static[TS 2]
C# weak[TS 3] implicit with optional explicit typing nominal static[TS 4]
Clean strong implicit static
Clojure strong implicit with optional explicit typing dynamic
COBOL strong explicit nominal static
ColdFusion (CFML) strong implicit dynamic
Common Lisp strong implicit with optional explicit typing structural for implicit typing, nominal for explicit typing dynamic, some static checking(depending on implementation)
Curl strong nominal
Cython strong implicit with optional explicit typing nominal (extension types) and structural (Python) dynamic with optional static typing
D weak[TS 3] explicit nominal static
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 n/a n/a n/a
Fortran strong explicit[TS 5] nominal static
Gambas strong explicit nominal
GLBasic strong explicit. Non-explicit declarations available through project options nominal static
Go[1] strong implicit with optional explicit typing structural static
Gosu strong partially implicit (local type inference) nominal (subclassing) and structural static
Groovy strong implicit with optional explicit typing dynamic with optional static typing
Harbour strong implicit with optional explicit typing dynamic
Haskell strong implicit with optional explicit typing nominal[2][3] static
Haxe strong implicit with optional explicit typing nominal (subclassing) and structural static with optional dynamic typing
Io strong implicit dynamic
ISLISP strong dynamic
J strong dynamic
Java strong[4] explicit nominal static
JavaScript weak implicit n/a dynamic
Julia strong implicit with optional explicit typing[5] structural for implicit typing, nominal for explicit typing dynamic
Joy strong dynamic
Kotlin strong partially implicit (local type inference) nominal static
LabVIEW strong
Lua strong implicit dynamic
Maple strong dynamic
Mathematica strong dynamic
MATLAB M-code strong dynamic
Modula-2 weak[TS 3] explicit nominal static
Modula-3 weak[TS 3] explicit structural static
MUMPS (M) typeless n/a n/a n/a
Oberon strong explicit nominal static and partially dynamic[TS 6]
Objective-C strong explicit nominal dynamic with optional static typing[6]
OCaml strong implicit with optional explicit typing nominal for records,[7] structural for objects[3][8] static
Object Pascal strong explicit nominal static
Opa strong implicit with optional explicit typing structural static
Oxygene weak implicit static
Oz-Mozart strong implicit structural dynamic
Pascal weak[TS 3] explicit nominal static
Perl 5 implicit dynamic
PHP implicit with optional explicit typing nominal dynamic
Plus strong explicit structural static, dynamic (optional)
Prolog dynamic
Pure dynamic
Python strong implicit (with optional explicit typing as of 3.5) n/a dynamic
Raku partially implicit[TS 7] dynamic with optional static typing
REBOL strong implicit dynamic
Rexx typeless n/a, implicit wrt numbers n/a static+dynamic wrt numbers
RPG weak static
Ruby strong implicit n/a dynamic
Rust strong explicit with optional implicit typing[9] mostly nominal static
S dynamic
S-Lang strong implicit dynamic
Scala strong partially implicit (local type inference) nominal (subclassing) and structural static
Scheme strong implicit dynamic (latent)
Seed7 strong explicit nominal static
Simula strong static[TS 8]
Smalltalk strong implicit dynamic
Swift strong partially implicit (local type inference) nominal (subclassing) and structural static
Standard ML strong implicit with optional explicit typing structural static
Tcl dynamic
TypeScript ? optional structural static
Visual Basic strong implicit with optional explicit typing nominal static
Visual Basic .NET weak[TS 3] explicit static
Visual Prolog strong partially implicit nominal static
Wolfram Language strong dynamic
Windows PowerShell strong implicit dynamic
XL strong nominal static
Xojo strong explicit nominal static
XPath/XQuery strong partially implicit nominal dynamic with optional static typing
Dart strong[10] gradual typing nominal static with optional dynamic typing
Language Type safety Type expression Type compatibility among composites Type checking

Notes

  1. Unsafe operations are well isolated by a "Unchecked_" prefix.
  2. with optional dynamic type casting (see dynamic cast)
  3. It is almost safe, unsafe features are not commonly used.
  4. with optional dynamic type (see dynamic member lookup)
  5. Optionally, typing can be explicitly implied by the first letter of the identifier (known as implicit typing within the Fortran community).
  6. dynamic checking of type extensions i.e. inherited types
  7. explicit for static types
  8. optional for formal and virtual procedures

References

  1. The Go Programming Language Specification
  2. Löh, Andres. "Why does Haskell not have records with structural typing?". Stack Overflow. Archived from the original on 2016-03-14. Retrieved 2020-04-13.
  3. King, Alexis (2020-01-19). "No, dynamic type systems are not inherently more open". lexi-lambda.github.io. Archived from the original on 2020-03-01. Retrieved 2020-04-13.
  4. Sheng Liang, Gilad Bracha. Dynamic class loading in the Java virtual machine. Volume 33, Issue 10 of ACM SIGPLAN Notices, October 1998.
  5. https://docs.julialang.org/en/latest/manual/types/
  6. Developer.apple.com Archived June 10, 2009, at the Wayback Machine
  7. "Record · Reason". reasonml.github.io. Archived from the original on 2020-03-31. Retrieved 2020-04-13.
  8. "Structural type system", Wikipedia, 2019-03-29, retrieved 2020-04-13
  9. "rust-lang/rustc-dev-guide". GitHub. Retrieved 2020-04-08.
  10. "The Dart type system". dart.dev. Retrieved 2020-04-08.
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.