richw@ada-uts.UUCP (10/24/85)
Does anyone know of any languages that either: 1) Attempts to do compile-time type-checking via "type inference"? That is, by analyzing the data flow of a program, the compiler tells you when it's sure that a type mismatch occurs -- this allows the programmer to not explicitly declare types. Yes, I know that this can lead to situations where a variable may refer to objects of several types, and is thus not perfect. I'm still curious to know if systems exist which try this. or... 2) Includes BOTH compile-time types and run-time, "manifest" types? By compile-time type, I mean that the type of an object is only known by the compiler during compilation -- at run-time, there are no flags (or the like) attached to data marking its type. Manifest types refer to objects which do have such flags indicating type. As an example, Lisp objects will have bits associated with them indicating whether they're atoms, lists, etc. Since I believe both type-systems have advantages, I'm curious to see if any languages have tried getting the benefits of both. No preference for posting responses vs. personal E-mail. Thanks "in advance", --- Rich Wagner
guido@boring.UUCP (10/27/85)
In article <15100005@ada-uts.UUCP> richw@ada-uts.UUCP writes: >Does anyone know of any languages that either: >1) Attempts to do compile-time type-checking via "type inference"? > That is, by analyzing the data flow of a program, the compiler > tells you when it's sure that a type mismatch occurs -- this allows > the programmer to not explicitly declare types. "B" does exactly this. E.g., after looking at PUT t[a+1] IN b \ this is B syntax for b := t[a+1] the system knows that 't' is a table (array) whose keys are numbers, that 'a' is a number, and that 'b' has the same type as the elements of 't'. See reference [1]. > Yes, I know that this can lead to situations where a variable may refer > to objects of several types, and is thus not perfect. What you see here as a defect can actually be a useful extension to a language: "generic" procedures are now for free! This, too is provided by B. See also reference [2]. >2) Includes BOTH compile-time types and run-time, "manifest" types? > By compile-time type, I mean that the type of an object is only > known by the compiler during compilation -- at run-time, there > are no flags (or the like) attached to data marking its type. > Manifest types refer to objects which do have such flags indicating > type. We are planning an extension to B to allow this, without disturbing the existent type system. (We don't have publishable material on this, yet.) References: [1] L.G.L.T. Meertens, Draft Proposal for the B Programming Language. Mathematisch Centrum, Amsterdam, 1981. ISBN 90 6169 238 2. [2] R. Milner, A theory of type polymorphism in programming, Journal of Computer and System Sciences, vol 17 (1978), 348-375. Disclaimer: We are well aware of the fact that there is another language called "B", in use at Waterloo University for system programming on old hardware. Please don't post followups saying this again! In the near future, "our" B will be renamed to ABC and at the same time revised at many minor points. -- Guido van Rossum, CWI, Amsterdam (guido@mcvax.UUCP)
db@cstvax.UUCP (Dave Berry) (10/28/85)
In article <15100005@ada-uts.UUCP> richw@ada-uts.UUCP writes: >Does anyone know of any languages that either: >1) Attempts to do compile-time type-checking via "type inference"? ML is a strongly-typed functional language with type inference. See "A proposal for Standard ML" by Robin Milner in the 1984 LISP conference. The language is older than that, but has just been standardised. It includes abstract datatypes, higher-order functions & polymorphism. You can define your own infix operators, and updatable values are provided if you need them. There's also a variant called lazy ML. The original paper detailing the inference scheme is "A theory of type polymorphism in programming", by Robin Milner in the Journal of Computer & System Sciences 17 (1978) pp 348-375. -- Dave Berry. CS postgrad, Univ. of Edinburgh ...mcvax!ukc!cstvax!db
craig@dcl-cs.UUCP (Craig Wylie) (10/28/85)
In reference to your question about languages using compile and runtime type checking I believe that POLY developed at the University of Glagow, Scotland, Great Britain - may include facilities such as this. There is a book on the subject :- Polymorphic programming languages Design and implementation publ: Ellis Horwood by David M. Harland Craig.
bob@cstvax.UUCP (Bob Harper) (10/29/85)
In article <15100005@ada-uts.UUCP> richw@ada-uts.UUCP writes: > >Does anyone know of any languages that either: > >1) Attempts to do compile-time type-checking via "type inference"? > That is, by analyzing the data flow of a program, the compiler > tells you when it's sure that a type mismatch occurs -- this allows > the programmer to not explicitly declare types. Yes, I know that > this can lead to situations where a variable may refer to objects > of several types, and is thus not perfect. I'm still curious to > know if systems exist which try this. > The programming language ML developed here at Edinburgh C.S. does just that. The use of type inference in programming was pioneered by Robin Milner in the design of ML (references below). ML is a strongly--typed, polymorphic functional programming language that was originally designed as the meta-- language (hence the name) for LCF, a logic for reasoning about programs. It has recently been revamped and standardized, and is now known as Standard ML. The language can be separated into two major components: the core language and the module facility. The core language implementation is complete and available; the module facility implementation is in progress. Enough advertising. The type system of ML has the property that no well--typed program can incur a type error at run time (where a type error includes things like trying to add a string to a boolean), and furthermore every program has a unique most--general type that can be automatically inferred without any type declarations by the user. The phrase ``most--general'' can be made mathemat-- ically precise, but, roughly speaking, it means that the ML compiler assigns the broadest meaningful type that it can. An example will help. Consider the function defined as follows: fun id(x) = x; This function takes a value x as argument and returns x as result. What type should id have? It clearly does not care whether the argument is an integer or a boolean or a function or a list or whatever --- the functional behavior is the same in all cases. Therefore the type assigned to id is not, say, int->int or bool->bool or ... but rather 'a->'a, where 'a (pronounced ``alpha'') is a type variable ranging over types. For id to have the type 'a->'a means that it can be applied to an argument of type 'a (for any type at all), and it returns a value of type 'a (the same 'a). This means that we can apply id to several arguments of vastly different types. All of the following uses are legal, and their type is given: id(3) int id(true) bool id(id) ('a->'a)->('a->'a) [!] The combined fact of inferring a most--general type together with the ability to use functions at several distinct types (all instances of the most general type) is called polymorphism. The function id is polymorphic (literally, many shapes) because it can take and returns values of many different types. (The term was coined by Strachey; he distinguished two forms: parametric and ad--hoc polymorphism; the former is what ML gives, the latter is now called ``overloading'', whereby the same identifier is used to refer to *different* functions, whereas here the identifier id refers to exactly *one* function: the compiler does *not* build different versions of id, one for each type used. Thus ML provides a much more elegant way of achieving polymorphism than does, say, ADA, which simply macro expands each use for each type argument.) By the way, there is no problem about a variable referring to objects of several different types. SML accounts for polymorphic assignment in more or less the same way as outlined above for functions, and thus preserves strong typing without sacrificing type inference or compile--time typechecking. Here are some salient points about SML: 1. Functions are first--class objects (that is what we mean by saying that SML is a functional language). 2. SML is statically (lexically) scoped. (I'll be happy to take on any dynamic scoping fans if they'd like.) 3. SML has imperative constructs (assignment, iteration), but also has a purely functional subset. 4. SML has an extensible type system, including simple type abbreviation, definition of new structural types (like trees or whatever), and definition of abstract types (stacks and the like). 5. SML is polymorphic and provides complete compile--time type inference. 6. SML has a module facility to support the structuring of large programs and to provide facilities for separate compilation and linking. This is getting long--winded, so I'll end with a reference list: 1. Robin Milner, ``A theory of type polymorphism in programming'', JCSS 17(3), December, 1978. 2. Michael Gordon, Robin Milner, and Christopher Wadsworth, ``Edinburgh LCF'', Springer Verlag LNCS 78 (1979). 3. Luis Damas and Robin Milner, ``Principal type schemes for functional programs'', Proc. 9th POPL, 1982. 4. Robert Harper, David MacQueen, and Robin Milner, ``The definition of Standard ML'' (to appear as Edinburgh CS Technical Report). 5. David MacQueen, ``Modules for Standard ML'', Bell Labs, October, 1985. (see also POPL in January 86). 6. Luca Cardelli, ``Amber'', Bell Labs, 1985. (a descendant of ML). >or... > >2) Includes BOTH compile-time types and run-time, "manifest" types? > By compile-time type, I mean that the type of an object is only > known by the compiler during compilation -- at run-time, there > are no flags (or the like) attached to data marking its type. > Manifest types refer to objects which do have such flags indicating > type. As an example, Lisp objects will have bits associated with > them indicating whether they're atoms, lists, etc. > Since I believe both type-systems have advantages, I'm curious > to see if any languages have tried getting the benefits of both. > >No preference for posting responses vs. personal E-mail. > >Thanks "in advance", >--- Rich Wagner Luca Cardelli's language Amber, a direct descendant of ML, provides for an elegant scheme of associating a type with a value at run time in such a way that strong typing is preserved. Objects with a type attached are called ``dynamics'' because they have a dynamically (rather than statically) determined type. Amber successfully combines polymorphism, type inference, type inheritance (as in Smalltalk), and dynamic types into a single well--defined, manageable type system. Bob Harper UUCP: ... mcvax!ukc!{hwcs,kcl-cs,ucl-cs,edcaad}!cstvax!bob ARPA: bob%cstvax.ed@ucl-cs.arpa tel: +44 31 667 1081 ext. 2697 mail: Department of Computer Science, University of Edinburgh, The King's Buildings (JCMB), Mayfield Road, Edinburgh EH9 3JZ, Great Britain -- Bob Harper UUCP: ... mcvax!ukc!{hwcs,kcl-cs,ucl-cs,edcaad}!cstvax!bob ARPA: bob%cstvax.ed@ucl-cs.arpa tel: +44 31 667 1081 ext. 2697 mail: Department of Computer Science, University of Edinburgh, The King's Buildings (JCMB), Mayfield Road, Edinburgh EH9 3JZ, Great Britain
msp@ukc.UUCP (M.S.Parsons) (10/29/85)
In article <6@cstvax.UUCP> db@cstvax.UUCP (Dave Berry) writes: >In article <15100005@ada-uts.UUCP> richw@ada-uts.UUCP writes: >>Does anyone know of any languages that either: >>1) Attempts to do compile-time type-checking via "type inference"? > >ML is a strongly-typed functional language with type inference. > Another language that does this is "Miranda", developed by David Turner at the University of Kent. Ref - Miranda: a non strict functional language with polymorphic types, in Functional Programming Languages and Computer Architecture (Lecture Notes in Computer Science 201), Springer-Verlag 1985
rcd@opus.UUCP (Dick Dunn) (10/30/85)
> Does anyone know of any languages that either: > ...(item deleted) > or... > > 2) Includes BOTH compile-time types and run-time, "manifest" types? > By compile-time type, I mean that the type of an object is only > known by the compiler during compilation -- at run-time, there > are no flags (or the like) attached to data marking its type. > Manifest types refer to objects which do have such flags indicating > type... Terminology problem here: "Manifest" types are types known to the compiler. Types known only at runtime are called "latent" types. Roughly the same meanings are associated with "static types" (known to the compiler) and "dynamic types" (known at runtime; more to the point, changeable at runtime). There are various examples of languages which have both manifest and latent types. In the common examples, latent types occur only in a few well- defined situations--in order to allow the compiler to make as much use of manifest type information as possible. Pascal's variant record is a weak example; the active variant of the record is determined by a "flag", namely the tagfield just ahead of the variant portion of the record. I say it's a weak example because the burden is on the programmer to examine the tagfield and act accordingly. A better example is the ALGOL 68 union. Access to a particular element ("variant" as it were) of the union is achieved by means such as a case-conformity clause, which is a case statement whose selection is based on the (hidden) type indicator of a union. (Yes, I know I should be saying things like "object" and "united from types..." Forgive me, ALGOL 68 aficionados; I'm trying to use common terms.) In a case-conformity, you can't get to a section of code that assumes an inappropriate type. Another method of access is the "conforms-to-and-becomes", an assignment operator that guards against inappropriate type. -- Dick Dunn {hao,ucbvax,allegra}!nbires!rcd (303)444-5710 x3086 ...At last it's the real thing...or close enough to pretend.
richw@ada-uts.UUCP (10/31/85)
First of all, thanks for all the replies; I've got quite a bit of reading to do... >>> 2) Includes BOTH compile-time types and run-time, "manifest" types? I apologize for not being more specific about "manifest" types (see below for a reference to the text from which I grabbed the term). I realize now that unions (of C) or variants (of Pascal) or oneofs/variants (of CLU) might be lumped in this category. These aren't quite what I was curious about because they are types which represent a union of a _finite_ set of other types. I was curious about data which stored the name (or something) of its type, and thus could be ANY one type of the "infinite" number of types available (assuming the language provided for user-defined types). Since the term, "manifest", apparently isn't as universal as I'd assumed: > Terminology problem here: "Manifest" types are types known to the > compiler. Types known only at runtime are called "latent" types. > Roughly the same meanings are associated with "static types" (known to the > compiler) and "dynamic types" (known at runtime; more to the point, > changeable at runtime). ...let me quote my source. I used the term "manifest" after seeing it in: "Structure and Interpretation of Computer Programs", by Abelson, Sussman, & Sussman Specifically, page 132 says: "A data object that has a type that can be recognized and tested is said to have _manifest_ type." The text then goes on to describe a scheme (no pun intended) for doing generic arithmetic using tagged data. Again, thanks for the replies. -- Rich Wagner