Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!yale!cmcl2!lanl!jlg From: jlg@lanl.gov (Jim Giles) Newsgroups: comp.society.futures Subject: Re: C's sins of commission (was: (pssst...fortran?)) Message-ID: <63483@lanl.gov> Date: 19 Sep 90 22:33:39 GMT References: <18377@ultima.socs.uts.edu.au> Organization: Los Alamos Natl Lab, Los Alamos, N.M. Lines: 123 From article <18377@ultima.socs.uts.edu.au>, by jeremy@ultima.socs.uts.edu.au (Jeremy Fitzhardinge): > In comp.society.futures you write: > [...] > |4) Sequences. An ordered collection of zero or more objects to be > | accessed in a specific order. [...] > > How does this differ from an array (or vica versa)? Is it that a sequence > is a completely dynamic object, where arrays are created with a specific > size (whether it be at compile or run time)? You seem to imply this later. > Is an object in a sequence of any type? Do all objects have to be the same > type? I guess a sequence of unions would achieve that effect while still > only allowing a sequence of one type. The answers to your questions are: 1) ther're different (see below); 2) exactly, arrays are fixed size/shape, sequences are always one-d and variable length (initialized empty unless the declaration does an initialization); 3) and 4) "sequence" is a declaration attribute which can be applied to any type - all elements of a sequence have the same type; 5) exactly, all the elements of a sequence can be in the same union type - the union can be collections of any types. Examples: Integer sequence :: x !empty sequence of integers Integer sequence(0:256:16) :: y !empty sequence, no space initially !allocated (the zero), max space is !256 elements, allocate in 16 element !chunks. ASCII sequence :: s !empty character string - ASCII char sequence :: ss = "abc" !character string in native character !set (which may or may not be ASCII), !initial value is three long "abc". !quotes is syntactic sugar for character !sequence types. type u_test is union(integer, ASCII sequence) !declares a union type where members !are integers or ASCII strings u_test sequence :: directory !directory is a sequence of ints or !ASCII sequences (each element may differ). ... s = ss !native character set is automatically !converted to ASCII ss = ss | "def" !concatenate is '|', ss is "abcdef" ss(2:4) = "xyz" !substring usage, ss is "axyzef" x = (1,3,5) !parenthesis are sequence constructor !for non-character types ... Anyway, I think you get the picture. > [... unions ...] > Careful selection of the tagging mechanism would be needed, I suppose. > At a guess you would have some sort of tag field in the union that has > a number representing the current type of the union. Since the union > can be of any type (simple and derived) the actual tags used would have > to be decided at compile time. This would make linking individually > compiled modules and libraries using shared union types difficult, since > they would all have to use the same tagging convention. I think it > should become a task of the linker to organize this kind of thing. Have > something like a "tag table" along side the "symbol table", and treat > them similarly. Scoping of [union] types would have to be handled like > scoping of variables, with similar name-space conflicts. > [...] The type tags would indeed be in the representation of the object itself. As a practical matter, the union object would probably consist of a type tag and a reference (pointer) to the data that represents the object. This would permit arrays and sequences (etc.) of unions to be allocated without having to worry about variable space depending on the type of object actually stored. Note: this use of pointers would be hidden from the user's view and subject to stronger compiler control so that it shouldn't raise any concerns about aliasing and other abuse - this is no different that the fact that IF/THEN/ELSE uses GOTOs internally. The scoping of user defined types of all flavors (not just unions) is a problem that the linker has to worry about (or the run-time environment). Actually, the proper use of interface specifications and the requirement that the type declarations in the caller match the ones in the callee would simplify the loader's work in this regard. This would also be a safer approach from the user's point of view, since it would make the type assumptions the user is making very explicit. As a practical matter, the type definitions and function prototypes could be contained in an include file so that the user would not be forever retyping them. > [...] > How would you handle what is currently handled by pointers to functions > in C? [...] Functions are an 'atomic' data type. Their attributes include the number and type of their arguments as well as the type of their result (if any). A variable of type 'function' can be declared and assigned to. Function definitions declare a named function with a 'constant' attribute. A possible syntax is: !comment sin() and cos() are the usual trig functions !comment the exclamation point begins a comment !end-of-line ends a comment float function (float) :: x ! x is a variable whose type ! is the same as sin() and cos() if (some_condition) then x=sin !function name with arg list causes no evaluation else x=cos endif ... ans = x(0.123) !does either sin(0.123) or cos(0.123) Syntactic/semantic sugar (such as adding function constructors, etc.) would allow adding complete functional language support. No pointers are implied here - not necessarily even in the low-level implementation - the assignment _could_ actually copy the code for the function. As a practical matter, function assignment should only copy the local variable space of the function and use a pointer to the code. This would permit, for example, multiple copies of a random number generator with a different seed in each. J. Giles