Talk:Type system/Archive 1

message: Taku, I appreciate your intent, but the discussion of Liskov Substitution Principle was out of place the way it was.  I have removed it.
If we want to integrate all discussions of type systems into a single article, that's fine with me.  If we want to put the Liskov discussion into the Subtype article, that's fine too (though we ought to mention that Liskov's is only one definition of "subtype").  However, just unceremoniously sticking the Liskov stuff into this article is definitely not appropriate.
Furthermore, a redirect is certainly not appropriate.  "Liskov Substitution Principle" is not equivalent to "Datatype".  Therefore, while the LSP article could be a very small article that just points to Datatype, IMHO it should not be a redirect.  -- Doradus 14:25, 20 Sep 2003 (UTC)
replies: text: What I thought is that is LSP such a big topic? To me, it doesn't say more about what I know about subtypes. Since subtype is redirected to datatype, then it makes sense to me to merge LSP to here. Subtype certainly deserves to its own article, but for now it is fine to put a redirect to subtypes. If I use an analogy, it is like there is no object-oriented programming article while there is an article about what is a class. LSP looks out of place because this article should be expanded more and subtype should have its own article. -- Taku 00:12, 22 Sep 2003 (UTC)
replies: text: You make a good point.  I had thought "Subtype" had its own article.  Perhaps we should take a look at all the type-related pages (including LSP) and look for a way to merge them. -- Doradus 10:51, 22 Sep 2003 (UTC)
thread_title: Liskov substitution

message: There still seems to be some loose use of language in this article, particularly on the difference between the strong/weak value axis and the static/dynamic type-checking variable axis.
Type safety means that the language will not execute code which uses a value in an operation for which its type is not acceptable. Virtually all languages make some effort towards type safety, in the form of type-checking (be it static or dynamic) and type-conversion. A failure of type-safety occurs in C or assembler when one treats the memory location of a short integer as if it contained a pointer -- and indirecting through the "pointer", one reaches a nonsense value.
Static type-checking means that the type-safety of a program is verified at compile-time, in terms of its variables. Static type-systems may require type declaration, or may use type inference -- either way, a type is assigned to each variable and function argument, and it is shown that no type-unsafe calls are made. Dynamic type-checking means that types are checked at run-time, in terms of argument values. A language which does not check types at run-time (e.g. C) does not have dynamic type-checking.
Static type-checking has been called incompatible with certain kinds of dynamic metaprogramming. This is the topic of a current controversy on comp.lang.lisp which may be enlightening (when it isn't being flamy).
Strong typing means that a value of one type may not legally be used in place of a value of another type. The set of operations which will accept a type is exactly the set of operations defined in terms of that type. Values must be converted or cast.
: Then the Scheme language is strongly typed rather than weakly typed, and the article's table should be corrected because of that. E.g. you have to explicitly convert between exact and inexact integers. But AFAIK, you can not add own types to the given, strong type system. --Thomas Hafner
Weak typing is the opposite: conversion is automatic and implicit. Weak typing does not imply that type-unsafe operations must be executed: it does imply that undesirable conversions (such as number truncation) may occur in order to prevent same. A single language may be strong with respect to some type differences, and weak w.r.t. others; weak typing might be more pleasantly called permissive or implicit-conversion-ful. <TT>:)</TT>
http://cliki.tunes.org/Type%20System has a discussion of these and two other axes upon which type-systems can be described.
Static type-checking prevents you from compiling a program with type errors or undeclared ambiguities in it. Dynamic type-checking stops the type error from causing dangerous behavior, usually by stopping the program. Strong typing protects you from unexpected truncations and other conversion problems.
Here are some possible type-related bugs, and the way that different type systems respond to them:
* I tried to use an integer value as a pointer, and wrote junk data on top of something. Any type-safe system (static or dynamic) will prevent this, by raising a type error either at compile-time or run-time. A system which is weakly typed with respect to the integer/pointer distinction is type-unsafe on most computer architectures!
* I used an integer operation on a real number, but I don't really need the decimal part. A static strong type-system will raise an error at compile-time. A dynamic strong type-system will raise an error at run-time. A weak type-system will convert your real to an integer -- which is not a bug in this case, but see the next.
* I used an integer operation on a real number, and returned an incorrect answer because of it. Any strong type-system will prevent this. Type-systems which are weak (or "permissive") with respect to numeric conversion will not; they will cheerfully truncate your real.
* I used the string "69" where I meant the number 69. Only a type-system that is weak wrt the string/number distinction -- such as Perl's -- will accept this code.
* There's a library function which usually returns a Foo object, but sometimes returns integer zero to indicate error. I write a function which can only accept a Foo, and call it on the return of the library function. A static type-system will refuse to compile your function. A dynamic type-system will not raise a fuss until the erroneous case actually happens. Only a type-unsafe system (such as assembler) will let your code try to use the zero as if it were a Foo, and get corrupt data.
And here are some languages of each category:
*Static, strong: Haskell (type-inference); Java (type declaration)
*Static, weak: C (type declaration -- also, plenty of ways to get around the type-system and do something type-unsafe!)
*Dynamic, strong: Common Lisp (type declarations are optional); Python
*Dynamic, weak: Perl (loves to do implicit conversions ....)
--FOo 23:16, 15 Nov 2003 (UTC)
thread_title: Strong/weak vs. static/dynamic

message: In Subsection 2.1 Static and dynamic typing, in the paragraph that begins with "By contrast, a purely dynamically typed system," a code example is referenced that doesn't appear until later, in the next section, as if it would be close by.
What is the best way to fix this, do you think?
Ehn 19:59, 28 Jul 2004 (UTC)
thread_title: Examples

message: Latent typing redirects here, but there is no mention of it on this page, let alone a prominent one. - Furrykef 16:12, 4 Sep 2004 (UTC)
thread_title: Latent typing

message: * Type System Terminology may be usefull. --Michal Jurosz 14:44, 19 January 2006 (UTC)
thread_title:  Type System Terminology 

message: An anonymous editor added this section that seems mostly bogus or stuff already covered elsewhere in the article. I moved it here in case it motivates someone:
:Some dynamic languages use internal "tags" to track how a declaration happens, and some don't, relying on the value itself as the sole indicator of content. For example:
   a = "52";
   b = 52;
:In "tag-free" languages, the contents of variable "a" and "b" would be identical. In tagged dynamic languages, internally the variables would carry an internal flag(s) to indicte the type. If we could "X-ray" the variable storage inside a language "engine", we would see something resembling:
  Tagged Types:
  a: ["52", type: string]
  b: ["52", type: number]
  Untagged Types:
  a: ["52"]
  b: ["52"]
:In untagged languages, operator overloading is not very effective and more explicit operators are needed. For example, string concatenation may use an ampersand or period instead of a plus sign to avoid ambiguity. Some prefer this approach, saying "what you see is what you get". Which approach is favored is highly debated and seems to be a personal preference.
:Tagged dynamic languages usually have a standard operation or set of operations that return the "type" of a given variable. Such a function may be called "typeOf", "typeName", "type", "getType", etc. Non-tagged languages cannot have such (although they may have parsing-based validation operations such as "isNumber"). Some languages are partially tagged in that scalar types are not tracked, but the difference between compound types, such as arrays, and scalars is. It is possible to make this distinction blurred and/or automatic also, but in practice very few languages use such an approach.
:Using the tagged approach, types are checked by seeing that a variable or value has the appropriate tag. In some languages a math operation, for example, may refuse to compute with a value having a "string" type since it expects only numbers. Other languages will attempt to convert any string parameters encountered into a number by parsing the string and copying it into a temporary number. Non-tagged languages will always have to parse and validate to do such operations.
</blockquote>
--TuukkaH 12:02, 19 February 2006 (UTC)
thread_title:  Type "Tags" 

message: I have removed closures from the list of "advanced" constructs cited as more difficult to use in statically typed languages than dynamically typed ones.  If the word closure here means "function as first-class value", then as an ML programmer I disagree: I use those things all the time and they're not the least bit difficult -- on the contrary, I find that the higher in order my functions get, the more types help to keep me from getting confused.  I expect most ML or Haskell programmers would agree.  If you want to claim that closures are easier to use in dynamically typed languages, please either provide or cite a more detailed explanation of why. Cjoev 22:27, 14 April 2006 (UTC)
replies: text: You're right, that was a mistake.  Thanks for fixing that.  I still don't know about the correctness of my claim that some "advanced" constructs are easier to use in dynamically typed languages.  Perhaps what I should have said is that some "advanced" constructs are easier to use in languages that feature run-time execution of code, type introspection, closures, the ability to dynamically modify existing functions and attributes of existing objects, etc and by association dynamically typed languages tend to feature these things.  Hence in practice dynamically typed languages tend to be better for "avoiding patterns in code" by abstracting away those patterns.  However, in theory a statically typed language could do all of these things and simply require more typing.  This is why I'm not sure my claim has much validity.  But I figured I should "be bold" in editing, since in practice there does seem to be "something" different about dynamically typed languages in terms of flexibility. - Connelly 19:22, 19 April 2006 (UTC)
thread_title:  Closures easier with dynamic typing?? 

message: Strictly speaking, assembly language is NOT untyped. Why this is even mentioned in a page comparing high-level languages, I don't know.
But there are several points to be made about assembly, instead of the gross generalizations here and elsewhere:
* In most assembly languages, instructions operate on one of several predefined types: 1-, 2-, 4-, 8-byte integers, 4- and 8-byte reals, bits, etc. In some assembly languages there are even pseudo-instructions for declaring registers and data with these types. This is hardly "typeless". 
* Assembly may be considered "static" in its typing, because all primitive types are static --  In my 20 years of assembly programming, I've never seen an instruction which uses the contents of a datum to determine its type. The type is always implied as a part of the instruction or register.
* There may be special instructions which treat collections of bits and/or bytes in a special way, like a data structure, and which operate directly on registers or memory in terms of this data structure. This is seen more often in systems programming than in application programming, because the structures are very low-level, such as the page tables of the machine. Nonetheless, these data structures can be considered "types" in themselves. And don't forget grandma's vector machine.
* Variables such as hardware registers may have predefined or inferred type: On some architectures, registers can hold both integer and floating-point data, and only the instruction operating on the register determines the type of the data inside it. In others, the types of the registers are predefined: always integer or always FP, with restrictions on which instructions may operate on each of these sets of registers. Registers with inferred type tend to be friendlier to programming, because it makes things easier at procedure boundaries: If you call a routine and pass arguments in registers, the calling convention is simple and uniform if the registers' types are inferred -- the caller and callee simply have to agree on the types of the arguments. But if the registers are of predefined types, then you have to create complicated calling conventions on how arguments are passed, since how they are passed now depends on their type -- integers must go to one set of registers, while FP values must go to another set of registers, etc.
* More subtly, some architectures are strong or weak with respect to certain sub-types, such as unsigned vs. signed integers, even though the same might not hold in general -- it may be weaker in distinguishing between integer subtypes, than between integer and other types. On some architectures, signedness is a strong property, and there are separate instructions to perform signed and unsigned arithmetic. With the advent of Two's complement notation, signedness is largely a weak property on today's machines, and only certain things like comparison instructions, branch instructions, or condition codes, need to distinguish between signedness and unsignedness.
So I would say that assembly language is: Statically typed, "varied" in strong/weak (depends on the machine and assembly language syntax), unsafe, structural, and types may either be predefined or inferred (depends on the machine and assembly language syntax).
It is NOT "untyped", "always weak", or "undefined".
: I don't want to sound like I disagree with you entirely, but I think one has to be careful.  There is a distinction to be made between the formal types of the language -- sets of data recognized as different by the machine and to which different sets of operations apply -- and the informal types in the mind of the programmer, even if the latter were anticipated by the design of the hardware.  For example, on the x86 the contents of a 4-byte region of memory can be (1) used as an operand to an ALU instruction such as add, (2) loaded into a general-purpose register and then used as the address in a memory operand, or (3) loaded into an FPU register and used for floating-point arithmetic.  Any of these operations is allowed and produces a well-defined behavior (possibly an exception) no matter what the contents of those locations is.  This suggests that there is one type of "32-bit data", which supports all three of these kinds of operations -- in particular, integers, pointers and floats of the same size are not different types.  "Integer", "pointer" and "float" are refinements of the one 32-bit type that are unofficially used by the programmer to organize data so as to make the most productive use of the capabilities of the machine.  If one considers these types distinct, then one must conclude that assembly is weakly typed because it silently coerces between them (and not in particularly meaningful ways).  This is even more the case with larger data structures such as page tables.  One can put together any nonsensical mess that one wants and call it a "page table", and the hardware will not notice the difference; it will result in some well-defined, though not necessarily useful, behavior.  I conclude that "page table" is not a distinct type from any other type of data of the same size.
: On the other hand, since the IA-32 does use separate FPU registers for all floating-point operations, it does make sense to consider the extended-precision floats stored therein as a separate "type", since there are operations applicable to them that do not apply to anything else.  Moving data between the FPU and memory can be thought of as a type conversion operation. Cjoev 23:51, 18 April 2006 (UTC)
thread_title:  Assembly Language NOT untyped!!! 

message: "Static typing" -- for one -- is a term that is discussed before it is defined.  In fact the first two distinct references to this phrase (first in the preface, second in the section "Static and Dynamic Typing") seem to assume that the reader knows what it means, while *seeming* to explain what it means.  I do not think the term is *ever* defined in the article. But where else in Wikipedia would it be defined? 
This definition-free usage of expert terminology is a serious blunder in an expository article like this. Fixing it should not have to wait for someone's getting around to making separate pages for static and dynamic typing (as mentioned in Static/Dynamic Typing section above).71.224.204.167 07:14, 26 June 2006 (UTC)
thread_title: Discussing a term before it is defined 

message: Some languages have types that express concurrent/communicating processes (CSP ...)
or parallel execution. Where would these types fit? 84.62.137.188 18:11, 7 July 2006 (UTC)
thread_title: Concurrency Types