Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!wuarchive!udel!ee.udel.edu From: new@ee.udel.edu (Darren New) Newsgroups: comp.lang.misc Subject: Re: The search for heterogeneous lists is still on! Keywords: Thrust! Repost! Lunge! Message-ID: <49726@nigel.ee.udel.edu> Date: 4 Apr 91 00:12:25 GMT References: <167:Mar3121:32:0891@kramden.acf.nyu.edu> <49591@nigel.ee.udel.edu> <10977:Apr319:27:2891@kramden.acf.nyu.edu> Sender: usenet@ee.udel.edu Organization: University of Delaware Lines: 136 Nntp-Posting-Host: nigel.ee.udel.edu In article <10977:Apr319:27:2891@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >In article <49591@nigel.ee.udel.edu> new@ee.udel.edu (Darren New) writes: Just to recap and attempt to avoid confusion, the discussion (as I understand it) is whether there is such a thing as a "real" hetrogeneous collection, rather than either unions or bunches of callback functions. "unions" can be taken (from a later post of Dan's) to mean "the callee knows all possible types" rather than the C unions I thought he meant. I asked Dan to clarify some of his terms, which he did admirably. I herein attempt to present some hetrogeneous collections/functions using Dan's definitions. >A function taking a heterogeneous argument can be given types not >specifically anticipated by the function writer. This is a necessary, >though not sufficient, restriction, which still eliminates printf. OK. So this is part of your definition for hetrogeneous collections. >> I see unions as hetrogeneous types >> themselves. >Unions are not heterogeneous types. Period. I phrased this wrong. *In C*, unions are used primarily to save space, bang bits, or implement hetrogeneous types. In symbol tables, for example, they are used to implement multiple different interpretations of bits within the same array. That's why I prefaced my comment with "I see": because I understand that any given union is a fixed type, but in cases where they are used, they are usually used to declare a variable able to take on multiple types in reality but restricted to a single type formally. You recognise this by saying that unions could be implemented as structures except for the requirement that their elements overlap. Overlap is primarily of interest to space savers and bit bangers, not to hetrogeneous typists, since hetro-typists would not (on purpose) take advantage of the overlap by reading an element after assigning a different element. Hence, to define a structure as containing an integer, a float, and a char pointer and then to use only one of those entries for the lifetime of that structure would seem more like an implementation of dynamic typing on top of static-typing restrictions than it would the use of a homogenous type. That's not really clear, but it isn't too important because that isn't the point I want to address here. >I gave the canonical example of a heterogeneous type when I entered this >discussion: viz., the set of all (expressible) values. OK. In Smalltalk, I declare a variable alpha just by giving its name. I can assign to that variable any expressible value. That declaration hence (by your definition) names a variable of a hetrogeneous type. A collection of such variables (say, the locals of a method/function) would represent a hetrogeneous collection. Hence, Smalltalk supports hetrogeneous collections, not statically typed. The locals of a Smalltalk method thereby represent hetrogeneous collections (i.e., collections of hetrogeneous values) that are used in real life. >Among other >things, a heterogeneous array can contain types allowed by the language, >but not anticipated by whoever defines how the array is going to be used. This is how arrays are defined in Smalltalk. Every array in Smalltalk, including the global dictionary of declarations, is a real-life hetrogeneous array. It is not in any important sense an array of unions, nor is it always dealt with via function pointers. For example, looking up a name in the global dictionary does not involve any function pointers in any important sense, because all the names are of type Symbol and hence are all compared withe the same routine. However, the entries in the dictionary are all different types, namely 2-tuples of the form , where the ??? can be any expressible value. In C, you would not be able to represent such a declaration, because C does not have a declaration for "any expressible value." Hence, different tuples would have different types for their second entry and hence the tuples would be of different types. [an acceptable example of a module dealing with hetrogeneous lists is] >A module that does not know all the types it can deal with, but wants to >deal with more than just function pointers to perform operations. OK. There is a Smalltalk function that is called "instanceAt:" which takes a value of any type and an integer offset and retrieves the value at that offset within the passed-in value. There is another one called "class" which takes any value and returns the type of that value. A third operation "new" takes a type and creates a new value of that type. None of these deals with function pointers in any way. Each is implemented only as a primitive of the language, and hence is implemented only once, rather than once for each type. For example, I can write a function in Smalltalk that iterates through any array passed to it and creates a new array containing the classes of the elements of the array: DECLARE makeClasses: inArray ! outArray ! <- sorry, pipe key is broken outArray <- Array new: inArray size. 1 to: inArray size do: [ :index ! outArray at: index put: (inArray at: index) class ] ^ outArray In this code, I get an inArray which is a collection of any expressible values. The calls to the functions (to:do:, new:, at:put:, at:, class) could all be statically bound to their appropriate implementations, and there is no important sense in which I am dealing with "pointers to functions." However, there are undoubtably values of multiple types here, and I'm doing things (class) with those values. You say, "So where is the "real world" program? What about the "copy" operation, which takes a value and makes a copy of it? It uses "class" to determine the type for the new value, creates such a value using "new", and finially it iterates through the old value using "instanceAt:" to get the old values and "instanceAt:put:" to store them in the new value. Still looking for a C function that accepts a hetrogeneous type, how about, in C, the sizeof "function"? It can accept types and variables that I have declared in C that the compiler-writers could not have anticipated me declaring in any important sense. It does not deal in any way with function pointers. At any time in my program, I can pass it a variable containing any expressible value, and it will return the number of bytes that that value requires to be stored. That I can not pass is an expression, but only a variable, is a restriction that I don't understand (except on ease-of-compiler-implementation grounds). If you wish to say it doesn't count because it isn't a real function but rather is built into the compiler, I will merely take this as one of the advantages of dynamic typing: one doesn't need to kludge function-like things into the compiler merely because the user cannot do it him/herself. -- Darren -- --- Darren New --- Grad Student --- CIS --- Univ. of Delaware --- ----- Network Protocols, Graphics, Programming Languages, FDTs ----- +=+=+ My time is very valuable, but unfortunately only to me +=+=+ + When you drive screws with a hammer, screwdrivers are unrecognisable +