Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Type safety
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|Extent to which a programming language discourages type errors}} {{Type systems}} In [[computer science]], '''type safety''' and '''type soundness''' are the extent to which a [[programming language]] discourages or prevents [[type error]]s. Type safety is sometimes alternatively considered to be a property of facilities of a computer language; that is, some facilities are type-safe and their usage will not result in type errors, while other facilities in the same language may be type-unsafe and a program using them may encounter type errors. The behaviors classified as type errors by a given programming language are usually those that result from attempts to perform operations on [[value (computer science)|values]] that are not of the appropriate [[data type]], e.g., adding a [[String (computer science)|string]] to an [[Integer (computer science)|integer]] when there's no definition on how to handle this case. This classification is partly based on opinion. [[Type enforcement]] can be static, catching potential errors at [[compile time]], or dynamic, associating type information with values at [[Run time (program lifecycle phase)|run-time]] and consulting them as needed to detect imminent errors, or a combination of both.<ref>{{Cite web |title=What to know before debating type systems {{!}} Ovid [blogs.perl.org] |url=https://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html |access-date=2023-06-27 |website=blogs.perl.org}}</ref> Dynamic type enforcement often allows programs to run that would be invalid under static enforcement. In the context of static (compile-time) type systems, type safety usually involves (among other things) a guarantee that the eventual value of any [[expression (programming)|expression]] will be a legitimate member of that expression's static type. The precise requirement is more subtle than this β see, for example, [[subtyping]] and [[Polymorphism (computer science)|polymorphism]] for complications. ==Definitions== Intuitively, type soundness is captured by [[Robin Milner]]'s pithy statement that :Well-typed programs cannot "go wrong".<ref name="Milner 1978">{{Citation | last1 = Milner | first1 = Robin | title = A Theory of Type Polymorphism in Programming | journal = Journal of Computer and System Sciences | pages = 348β375 | volume = 17 | issue = 3 | year = 1978 | doi=10.1016/0022-0000(78)90014-4 | doi-access = free | hdl = 20.500.11820/d16745d7-f113-44f0-a7a3-687c2b709f66 | hdl-access = free }}</ref> In other words, if a type system is ''sound'', then expressions accepted by that type system must evaluate to a value of the appropriate type (rather than produce a value of some other, unrelated type or crash with a type error). Vijay Saraswat provides the following, related definition: :A language is type-safe if the only operations that can be performed on data in the language are those sanctioned by the type of the data.<ref name=saraswat-java>{{cite web|last=Saraswat |first=Vijay | date=1997-08-15 |title=Java is not type-safe |url=http://www.cis.upenn.edu/~bcpierce/courses/629/papers/Saraswat-javabug.html |access-date=2008-10-08 }}</ref> However, what precisely it means for a program to be "well typed" or to "go wrong" are properties of its [[static semantics|static]] and [[dynamic semantics]], which are specific to each programming language. Consequently, a precise, formal definition of type soundness depends upon the style of formal semantics used to specify a language. In 1994, Andrew Wright and [[Matthias Felleisen]] formulated what has become the standard definition and proof technique for type safety in languages defined by [[operational semantics]],<ref name="Wright and Felleisen 1994">{{cite journal |last1=Wright |first1=A. K. |last2=Felleisen |first2=M. |title=A Syntactic Approach to Type Soundness |journal=Information and Computation |date=15 November 1994 |volume=115 |issue=1 |pages=38β94 |doi=10.1006/inco.1994.1093 |language=en |issn=0890-5401|doi-access=free }}</ref> which is closest to the notion of type safety as understood by most programmers. Under this approach, the semantics of a language must have the following two properties to be considered type-sound: ;Progress: A well-typed program never gets "stuck": every [[Expression (computer science)|expression]] is either already a [[Value (computer science)|value]] or can be reduced towards a value in some well-defined way. In other words, the program never gets into an undefined state where no further transitions are possible. ;Preservation (or [[subject reduction]]): After each evaluation step, the type of each expression remains the same (that is, its type is ''preserved''). A number of other formal treatments of type soundness have also been published in terms of [[denotational semantics]] and [[structural operational semantics]].<ref name="Milner 1978" /><ref>{{cite book |last1=Damas |first1=Luis |last2=Milner |first2=Robin |title=Proceedings of the 9th ACM SIGPLAN-SIGACT symposium on Principles of programming languages - POPL '82 |chapter=Principal type-schemes for functional programs |date=25 January 1982 |pages=207β212 |doi=10.1145/582153.582176 |chapter-url=https://dl.acm.org/doi/10.1145/582153.582176 |publisher=Association for Computing Machinery|isbn=0897910656 |s2cid=11319320 }}</ref><ref>{{cite thesis |last1=Tofte |first1=Mads |title=Operational Semantics and Polymorphic Type Inference |date=1988 |url=https://era.ed.ac.uk/handle/1842/6606 |language=en}}</ref> ==Relation to other forms of safety== In isolation, type soundness is a relatively weak property, as it essentially just states that the rules of a type system are internally consistent and cannot be subverted. However, in practice, programming languages are designed so that well-typedness also entails other, stronger properties, some of which include: * Prevention of illegal operations. For example, a type system can reject the expression <code>3 / "Hello, World"</code> as invalid, because the division [[Operator (computer programming)|operator]] is not defined for a [[string (computer science)|string]] [[divisor]]. * [[Memory safety]] ** Type systems can prevent [[wild pointer]]s that could otherwise arise from a pointer to one type of object being treated as a pointer to another type. ** More sophisticated type systems, such as those supporting [[dependent type]]s, can detect and reject out-of-bound accesses, preventing potential [[buffer overflow]]s.<ref>{{cite book |last1=Henriksen |first1=Troels |last2=Elsman |first2=Martin |title=Proceedings of the 7th ACM SIGPLAN International Workshop on Libraries, Languages and Compilers for Array Programming |chapter=Towards size-dependent types for array programming |date=17 June 2021 |pages=1β14 |doi=10.1145/3460944.3464310 |chapter-url=https://dl.acm.org/doi/10.1145/3460944.3464310 |publisher=Association for Computing Machinery|isbn=9781450384667 |s2cid=235474098 }}</ref> * [[Logic error]]s originating in the [[semantics]] of different types. For instance, inches and millimeters may both be stored as integers, but should not be substituted for each other or added. A type system can enforce two different types of integer for them. ==Type-safe and type-unsafe languages== Type safety is usually a requirement for any toy language (i.e. [[esoteric language]]) proposed in academic programming language research. Many languages, on the other hand, are too big for human-generated type safety proofs, as they often require checking thousands of cases. Nevertheless, some languages such as [[Standard ML]], which has rigorously defined semantics, have been proved to meet one definition of type safety.<ref>[http://www.smlnj.org/sml.html Standard ML]. Smlnj.org. Retrieved on 2013-11-02.</ref> Some other languages such as [[Haskell (programming language)|Haskell]] are ''believed''{{discuss}} to meet some definition of type safety, provided certain "escape" features are not used (for example Haskell's {{mono|unsafePerformIO}}, used to "escape" from the usual restricted environment in which I/O is possible, circumvents the type system and so can be used to break type safety.<ref>{{cite web |url=http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO-Unsafe.html#v:unsafePerformIO |title=System.IO.Unsafe |work=GHC libraries manual: base-3.0.1.0 |access-date=2008-07-17 |archive-url=https://web.archive.org/web/20080705163908/http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO-Unsafe.html#v:unsafePerformIO |archive-date=2008-07-05 |url-status=dead }}</ref>) [[Type punning]] is another example of such an "escape" feature. Regardless of the properties of the language definition, certain errors may occur at [[Run time (program lifecycle phase)|run-time]] due to bugs in the implementation, or in linked [[library (computer science)|libraries]] written in other languages; such errors could render a given implementation type unsafe in certain circumstances. An early version of Sun's [[Java virtual machine]] was vulnerable to this sort of problem.<ref name=saraswat-java /> == Strong and weak typing == {{Main|Strong and weak typing}} Programming languages are often colloquially classified as strongly typed or weakly typed (also loosely typed) to refer to certain aspects of type safety. In 1974, [[Barbara Liskov|Liskov]] and Zilles defined a strongly-typed language as one in which "whenever an object is passed from a calling function to a called function, its type must be compatible with the type declared in the called function."<ref>{{cite journal | citeseerx = 10.1.1.136.3043 | title = Programming with abstract data types | first1 = B | last1 = Liskov | first2 = S | last2 = Zilles | journal = ACM SIGPLAN Notices | volume = 9 | issue = 4 | pages = 50β59 | year = 1974 | doi=10.1145/942572.807045}}</ref> In 1977, Jackson wrote, "In a strongly typed language each data area will have a distinct type and each process will state its communication requirements in terms of these types."<ref>{{cite book | first1 = K. | last1 = Jackson | title = Design and Implementation of Programming Languages | chapter = Parallel processing and modular software construction | year = 1977 | volume = 54 | pages = 436β443 | doi = 10.1007/BFb0021435 | series = Lecture Notes in Computer Science | isbn = 3-540-08360-X }}</ref> In contrast, a weakly typed language may produce unpredictable results or may perform implicit type conversion.<ref>{{cite web | title =CS1130. Transition to OO programming. β Spring 2012 --self-paced version | date = 2005 | publisher = Cornell University, Department of Computer Science | url = https://www.cs.cornell.edu/courses/cs1130/2012sp/1130selfpaced/module1/module1part4/strongtyping.html | access-date = 2023-09-15}}</ref> == Memory management and type safety == Type safety is closely linked to [[memory safety]]. For instance, in an implementation of a language that has some type <math>t</math> which allows some bit patterns but not others, a [[dangling pointer]] memory error allows writing a bit pattern that does not represent a legitimate member of <math>t</math> into a dead [[Variable (programming)|variable]] of type <math>t</math>, causing a type error when the variable is read. Conversely, if the language is memory-safe, it cannot allow an arbitrary integer to be used as a [[pointer (computer programming)|pointer]], hence there must be a separate pointer or reference type. As a minimal condition, a type-safe language must not allow [[dangling pointer]]s across allocations of different types. But most languages enforce the proper use of [[abstract data type]]s defined by programmers even when this is not strictly necessary for memory safety or for the prevention of any kind of catastrophic failure. Allocations are given a type describing its contents, and this type is fixed for the duration of the allocation. This allows type-based [[alias analysis]] to infer that allocations of different types are distinct. Most type-safe languages use [[Garbage collection (computer science)|garbage collection]]. Pierce says, "it is extremely difficult to achieve type safety in the presence of an explicit deallocation operation", due to the dangling pointer problem.<ref>{{cite book |last1=Pierce |first1=Benjamin C. |title=Types and programming languages |date=2002 |publisher=MIT Press |location=Cambridge, Mass. |isbn=0-262-16209-1 |page=158}}</ref> However [[Rust (programming language)|Rust]] is generally considered type-safe and uses a borrow checker to achieve memory safety, instead of garbage collection. ==Type safety in object oriented languages== In [[object oriented]] languages type safety is usually intrinsic in the fact that a [[type system]] is in place. This is expressed in terms of class definitions. A [[Class (computer science)|class]] essentially defines the structure of the objects derived from it and an [[Api#API in object-oriented languages|API]] as a ''contract'' for handling these objects. Each time a new object is created it will ''comply'' with that contract. Each function that exchanges objects derived from a specific class, or implementing a specific [[Interface (computer science)|interface]], will adhere to that contract: hence in that function the operations permitted on that object will be only those defined by the methods of the class the object implements. This will guarantee that the object integrity will be preserved.<ref>Type safety is hence also a matter of good class definition: public methods that modify the internal state of an object shall preserve the object itegrity</ref> Exceptions to this are object oriented languages that allow dynamic modification of the object structure, or the use of [[Reflection (computer science)|reflection]] to modify the content of an object to overcome the constraints imposed by the class methods definitions. ==Type safety issues in specific languages== === Ada === {{wikibooks|Ada Programming|Type System}} [[Ada programming language|Ada]] was designed to be suitable for [[embedded system]]s, [[device driver]]s and other forms of [[system programming]], but also to encourage type-safe programming. To resolve these conflicting goals, Ada confines type-unsafety to a certain set of special constructs whose names usually begin with the string {{mono|Unchecked_}}. Unchecked_Deallocation can be effectively banned from a unit of Ada text by applying {{mono|pragma Pure}} to this unit. It is expected that programmers will use {{mono|Unchecked_}} constructs very carefully and only when necessary; programs that do not use them are type-safe. The [[SPARK programming language]] is a subset of Ada eliminating all its potential ambiguities and insecurities while at the same time adding [[design by contract|statically checked contracts]] to the language features available. SPARK avoids the issues with [[dangling pointer]]s by disallowing allocation at run time entirely. Ada2012 adds [[design by contract|statically checked contracts]] to the language itself (in form of pre-, and post-conditions, as well as type invariants). === C === {{Wikibooks|C Programming}} The [[C (programming language)|C programming language]] is type-safe in limited contexts; for example, a compile-time error is generated when an attempt is made to convert a pointer to one type of structure to a pointer to another type of structure, unless an explicit cast is used. However, a number of very common operations are non-type-safe; for example, the usual way to print an integer is something like <code>printf("%d", 12)</code>, where the <code>%d</code> tells <code>printf</code> at run-time to expect an integer argument. (Something like <code>printf("%s", 12)</code>, which tells the function to expect a pointer to a character-string and yet supplies an integer argument, may be accepted by compilers, but will produce undefined results.) This is partially mitigated by some compilers (such as gcc) checking type correspondences between printf arguments and format strings. In addition, C, like Ada, provides unspecified or undefined explicit conversions; and unlike in Ada, idioms that use these conversions are very common, and have helped to give C a type-unsafe reputation. For example, the standard way to allocate memory on the heap is to invoke a memory allocation function, such as <code>[[malloc]]</code>, with an argument indicating how many bytes are required. The function returns an untyped pointer (type <code>void *</code>), which the calling code must explicitly or implicitly cast to the appropriate pointer type. Pre-standardized implementations of C required an explicit cast to do so, therefore the code <code>(struct foo *) malloc([[sizeof]](struct foo))</code> became the accepted practice.<ref name="knr">{{cite book | last = Kernighan | author1-link = Brian Kernighan | author2 = Dennis M. Ritchie | author-link2 = Dennis Ritchie | title = The C Programming Language | edition = 2nd | publisher = [[Prentice Hall]] | date = March 1988 | location = [[Englewood Cliffs, NJ]] | url = https://archive.org/details/cprogramminglang00bria/page/116 | isbn = 978-0-13-110362-7 | quote = In C, the proper method is to declare that malloc returns a pointer to void, then explicitly coerce the pointer into the desired type with a cast. | page = [https://archive.org/details/cprogramminglang00bria/page/116 116] | url-access = registration }}</ref> ===C++=== Some features of C++ that promote more type-safe code: * The [[new (C++)|new]] operator returns a pointer of type based on operand, whereas [[malloc]] returns a void pointer. * C++ code can use virtual functions and [[Template (programming)|templates]] to achieve polymorphism without void pointers. * Safer casting operators, such as [[dynamic cast]] that performs run-time type checking. * [[C++11#Strongly typed enumerations|C++11 strongly-typed enumerations]] cannot be implicitly converted to or from integers or other enumeration types. * [[C++11#Explicit conversion operators|C++ explicit constructors and C++11 explicit conversion operators]] prevent implicit type conversions. ===C#=== [[C Sharp (programming language)|C#]] is type-safe. It has support for untyped pointers, but this must be accessed using the "unsafe" keyword which can be prohibited at the compiler level. It has inherent support for run-time cast validation. Casts can be validated by using the "as" keyword that will return a null reference if the cast is invalid, or by using a C-style cast that will throw an exception if the cast is invalid. See [[C Sharp Syntax#Conversion operators|C Sharp conversion operators]]. Undue reliance on the [[C Sharp syntax#object class|object]] type (from which all other types are derived) runs the risk of defeating the purpose of the C# type system. It is usually better practice to abandon object references in favour of [[Generic programming#Generic programming in .NET|generics]], similar to templates in C++ and [[generics in Java]]. ===Java=== {{Wikibooks|Java Programming}} The [[Java programming language|Java language]] is designed to enforce type safety. Anything in Java ''happens'' inside an [[Object (computer science)|object]] and each object is an instance of a [[Class (computer programming)|class]]. To implement the ''type safety'' enforcement, each object, before usage, needs to be [[Memory allocation|allocated]]. Java allows usage of [[Primitive data type|primitive types]] but only inside properly allocated objects. Sometimes a part of the type safety is implemented indirectly: e.g. the class BigDecimal represents a floating point number of arbitrary precision, but handles only numbers that can be expressed with a finite representation. The operation BigDecimal.divide() calculates a new object as the division of two numbers expressed as BigDecimal. In this case if the division has no finite representation, as when one computes e.g. 1/3=0.33333..., the divide() method can raise an exception if no rounding mode is defined for the operation. Hence the library, rather than the language, guarantees that the object respects the contract implicit in the class definition. ===Standard ML=== {{Wikibooks|Standard ML Programming}} [[Standard ML]] has rigorously defined semantics and is known to be type-safe. However, some implementations, including [[Standard ML of New Jersey]] (SML/NJ), its syntactic variant [[Mythryl]] and [[MLton]], provide libraries that offer unsafe operations. These facilities are often used in conjunction with those implementations' [[foreign function interface]]s to interact with non-ML code (such as C libraries) that may require data laid out in specific ways. Another example is the SML/NJ [[read-eval-print loop|interactive toplevel]] itself, which must use unsafe operations to execute ML code entered by the user. === Modula-2 === Modula-2 is a strongly-typed language with a design philosophy to require any unsafe facilities to be explicitly marked as unsafe. This is achieved by "moving" such facilities into a built-in pseudo-library called SYSTEM from where they must be imported before they can be used. The import thus makes it visible when such facilities are used. Unfortunately, this was not consequently implemented in the original language report and its implementation.<ref>{{cite book|author=Niklaus Wirth|title=Programming in Modula-2|publisher=Springer Verlag|date=1985}}</ref> There still remained unsafe facilities such as the type cast syntax and variant records (inherited from Pascal) that could be used without prior import.<ref name="knightsoftype.blogspot.com">{{cite web|title=The Separation of Safe and Unsafe Facilities|url=http://knightsoftype.blogspot.com/2013/12/the-separation-of-safe-and-unsafe.html|access-date=24 March 2015}}</ref> The difficulty in moving these facilities into the SYSTEM pseudo-module was the lack of any identifier for the facility that could then be imported since only identifiers can be imported, but not syntax. <syntaxhighlight lang="modula2"> IMPORT SYSTEM; (* allows the use of certain unsafe facilities: *) VAR word : SYSTEM.WORD; addr : SYSTEM.ADDRESS; addr := SYSTEM.ADR(word); (* but type cast syntax can be used without such import *) VAR i : INTEGER; n : CARDINAL; n := CARDINAL(i); (* or *) i := INTEGER(n); </syntaxhighlight> The ISO Modula-2 standard corrected this for the type cast facility by changing the type cast syntax into a function called CAST which has to be imported from pseudo-module SYSTEM. However, other unsafe facilities such as variant records remained available without any import from pseudo-module SYSTEM.<ref>{{cite web|title=ISO Modula-2 Language Reference|url=http://www.excelsior-usa.com/doc/xds/isom2.html|access-date=24 March 2015}}</ref> <syntaxhighlight lang="modula2"> IMPORT SYSTEM; VAR i : INTEGER; n : CARDINAL; i := SYSTEM.CAST(INTEGER, n); (* Type cast in ISO Modula-2 *) </syntaxhighlight> A recent revision of the language applied the original design philosophy rigorously. First, pseudo-module SYSTEM was renamed to UNSAFE to make the unsafe nature of facilities imported from there more explicit. Then all remaining unsafe facilities where either removed altogether (for example variant records) or moved to pseudo-module UNSAFE. For facilities where there is no identifier that could be imported, enabling identifiers were introduced. In order to enable such a facility, its corresponding enabling identifier must be imported from pseudo-module UNSAFE. No unsafe facilities remain in the language that do not require import from UNSAFE.<ref name="knightsoftype.blogspot.com"/> <syntaxhighlight lang="modula2"> IMPORT UNSAFE; VAR i : INTEGER; n : CARDINAL; i := UNSAFE.CAST(INTEGER, n); (* Type cast in Modula-2 Revision 2010 *) FROM UNSAFE IMPORT FFI; (* enabling identifier for foreign function interface facility *) <*FFI="C"*> (* pragma for foreign function interface to C *) </syntaxhighlight> ===Pascal=== {{Wikibooks|Pascal Programming}} [[Pascal (programming language)|Pascal]] has had a number of type safety requirements, some of which are kept in some compilers. Where a Pascal compiler dictates "strict typing", two variables cannot be assigned to each other unless they are either compatible (such as conversion of integer to real) or assigned to the identical subtype. For example, if you have the following code fragment: <syntaxhighlight lang="pascal"> type TwoTypes = record I: Integer; Q: Real; end; DualTypes = record I: Integer; Q: Real; end; var T1, T2: TwoTypes; D1, D2: DualTypes; </syntaxhighlight> Under strict typing, a variable defined as {{mono|TwoTypes}} is ''not compatible'' with {{mono|DualTypes}} (because they are not identical, even though the components of that user defined type are identical) and an assignment of <code>T1 := D2;</code> is illegal. An assignment of <code>T1 := T2;</code> would be legal because the subtypes they are defined to ''are'' identical. However, an assignment such as <code>T1.Q := D1.Q;</code> would be legal. ===Common Lisp=== In general, [[Common Lisp]] is a type-safe language. A Common Lisp compiler is responsible for inserting dynamic checks for operations whose type safety cannot be proven statically. However, a programmer may indicate that a program should be compiled with a lower level of dynamic type-checking.<ref>{{cite web|title=Common Lisp HyperSpec|url=http://www.lispworks.com/documentation/HyperSpec/Body/d_optimi.htm|access-date=26 May 2013}}</ref> A program compiled in such a mode cannot be considered type-safe. == C++ examples == The following examples illustrates how C++ cast operators can break type safety when used incorrectly. The first example shows how basic data types can be incorrectly cast: <syntaxhighlight lang="cpp"> #include <iostream> using namespace std; int main () { int ival = 5; // integer value float fval = reinterpret_cast<float&>(ival); // reinterpret bit pattern cout << fval << endl; // output integer as float return 0; } </syntaxhighlight> In this example, <code>reinterpret_cast</code> explicitly prevents the compiler from performing a safe conversion from integer to floating-point value.<ref>{{cite web|url=http://en.cppreference.com/w/cpp/language/reinterpret_cast |title=reinterpret_cast conversion - cppreference.com |publisher=En.cppreference.com |date= |accessdate=2022-09-21}}</ref> When the program runs it will output a garbage floating-point value. The problem could have been avoided by instead writing <code>float fval = ival;</code> The next example shows how object references can be incorrectly downcast: <syntaxhighlight lang="cpp"> #include <iostream> using namespace std; class Parent { public: virtual ~Parent() {} // virtual destructor for RTTI }; class Child1 : public Parent { public: int a; }; class Child2 : public Parent { public: float b; }; int main () { Child1 c1; c1.a = 5; Parent & p = c1; // upcast always safe Child2 & c2 = static_cast<Child2&>(p); // invalid downcast cout << c2.b << endl; // will output garbage data return 0; } </syntaxhighlight> The two child classes have members of different types. When downcasting a parent class pointer to a child class pointer, then the resulting pointer may not point to a valid object of correct type. In the example, this leads to garbage value being printed. The problem could have been avoided by replacing <code>static_cast</code> with <code>dynamic_cast</code> that throws an exception on invalid casts.<ref>{{cite web|url=http://en.cppreference.com/w/cpp/language/dynamic_cast |title=dynamic_cast conversion - cppreference.com |publisher=En.cppreference.com |date= |accessdate=2022-09-21}}</ref> ==See also== *[[Type theory]] ==Notes== {{reflist}} ==References== *{{Cite book|author-link=Benjamin C. Pierce |last=Pierce |first=Benjamin C. |title=Types and Programming Languages |publisher=MIT Press |year=2002 |isbn=978-0-262-16209-8 |url=http://www.cis.upenn.edu/~bcpierce/tapl/}} *{{cite web|title=Type Safe |work=Portland Pattern Repository Wiki |url=http://c2.com/cgi/wiki?TypeSafe}} *{{Cite journal|last=Wright |first=Andrew K. |author2=Matthias Felleisen |title=A Syntactic Approach to Type Soundness |journal=Information and Computation |volume=115 |issue=1 |pages=38β94 |year=1994 |url=http://citeseer.ist.psu.edu/wright92syntactic.html |doi=10.1006/inco.1994.1093|doi-access=free |author2-link=Matthias Felleisen }} *{{Cite journal|first=Stavros |last=Macrakis |title=Safety and power |journal=ACM SIGSOFT Software Engineering Notes |volume=7 |issue=2 |pages=25β26 |date=April 1982 |doi=10.1145/1005937.1005941|s2cid=10426644 }} {{DEFAULTSORT:Type Safety}} [[Category:Programming language topics]] [[Category:Type theory]] [[Category:Articles with example Pascal code]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:Citation
(
edit
)
Template:Cite book
(
edit
)
Template:Cite journal
(
edit
)
Template:Cite thesis
(
edit
)
Template:Cite web
(
edit
)
Template:Discuss
(
edit
)
Template:Main
(
edit
)
Template:Mono
(
edit
)
Template:Reflist
(
edit
)
Template:Short description
(
edit
)
Template:Sister project
(
edit
)
Template:Type systems
(
edit
)
Template:Wikibooks
(
edit
)