Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10 5/3/83; site cornell.UUCP Path: utzoo!linus!decvax!harpo!floyd!vax135!cornell!hal From: hal@cornell.UUCP (Hal Perkins) Newsgroups: net.lang Subject: Re: Back to I/O operations in programming languages Message-ID: <5206@cornell.UUCP> Date: Wed, 31-Aug-83 22:22:18 EDT Article-I.D.: cornell.5206 Posted: Wed Aug 31 22:22:18 1983 Date-Received: Thu, 1-Sep-83 20:54:02 EDT References: <114@csd1.UUCP> Organization: Cornell Computer Science Lines: 83 I've got two comments on Mike's latest note. 1) The proposed "slow" property for data types--similar to Pascal's "packed". The packed keyword in Pascal is one of the things that didn't really work right. The intent of "packed" was to indicate to the implementation that storage for the data type can be economized, even if this requires extra time to access components of objects of the type. Furthermore, this should not affect the logical correctness of the program. (If I remember correctly, the Axiomatic Definition of Pascal by Hoare and Wirth doesn't even mention packed, except to say it has no effect on the meaning of the program.) But things didn't turn out this way, for exactly the same reasons that I couldn't mix arrays in the OS/360 file system with arrays in main storage efficiently. Procedure parameters must be treated differently if they are packed or unpacked structures or components of these. And there are a bunch of ad-hoc restrictions dealing with packed variables in Pascal. For instance, components of packed objects can't be passed as variable parameters because call-by-reference couldn't be implemented correctly unless the procedure were prepared to deal with a part-word address on word machines. And strings are always packed arrays of characters, which can't be mixed with just simple arrays of characters. So yes, it seems to me that one could add a "slow" attribute that would be similar to packed, and would have to have a similar set of ad hoc restrictions on how it could be used and how slow variables could be mixed with fast ones, passed as parameters, etc. From a practical standpoint, this would be a definite improvement on the usual baroque set of file-system functions needed to access external data. But in the long run, what is really needed is to understand how to deal with multiple concrete representations of the same abstract type in a way that allows one to program in terms of the abstract type without being bitten when the concrete representation is changed. "Packed", "slow", and other similar things should just affect the pragmatics of the program (time and space required to execute), and a correct program should remain correct when the representation is changed. This is hard, and I haven't seen any nice solutions yet. Ada does a little better than most languages. Derived types can be used to get different concrete representations for the same type, and there are games that can be played with generics, and it is possible to convert between related types. But it is still not possible to write a logically correct abstract program and then tinker with the representations without having to touch the abstract program sometimes. If anyone knows of a language that does this cleanly, please let me know, as it would save me a good bit of research work. 2) Applicative languages. One way to clean up the problem of I/O is to remember that the I/O in typical languages and systems is used for two completely different purpose. First, there is data that is read from and written to the outside world--things read from keyboards, printed on paper, signals used to control chemical plants, etc. These all have the characteristic that they are external to the computer system and are generally either sources or sinks of data. I doubt there will be any purely applicative way to deal with these--streams seem to be the simplest natural model. The other major use for typical I/O is the one that is mucks up clean programs the worst, and that is to use I/O instead of having a sufficiently large virtual store. This is also accompanied by using the same I/O libraries to implement various abstract data types. (One of the many reasons that the I/O documentation for many systems is so unpleasant and hard to understand--OS/360 is probably the worst--is that these two logical functions (shoveling data to and from the disk and organizing the disk data into some sort of data structure) are hopelessly mashed together into the same unmanagable package.) To simplify this mess, one can postulate a decent virtual storage system to take care of the primary<->secondary storage transfers and then deal with the logical organization of the data separately. We are still left with streams that communicate with the outside world, but we've gotten rid of a lot (in fact most) of the logical complexity of typical file systems. Maybe this would help. Then again, networks would seem to mess this up. Suppose you have a small computer paging over the network. Is the network a stream--a source and sink for pages--or is it somehow part of the sufficiently large virtual store that is supposed to make some of the I/O go away. It is probably both when viewed from different levels. Hal Perkins UUCP: {decvax|vax135|...}!cornell!hal Cornell Computer Science ARPA: hal@cornell BITNET: hal@crnlcs