From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site ucbvax.ARPA Path: utzoo!watmath!clyde!burl!ulysses!ucbvax!ucbrenoir!hilfingr From: hilfingr@UCBRENOIR (Paul Hilfinger) Newsgroups: net.lang.ada Subject: text_io problems solved(?), and some gripes Message-ID: <8509190859.AA00992@ucbrenoir.ARPA> Date: Thu, 19-Sep-85 04:59:04 EDT Article-I.D.: ucbrenoi.8509190859.AA00992 Posted: Thu Sep 19 04:59:04 1985 Date-Received: Sun, 22-Sep-85 05:28:37 EDT Sender: usenet@ucbvax.ARPA Organization: The ARPA Internet List-Id: A recent note finally gives me a chance to show off one of my favorite Ada examples. > Something that has always struck me as incredibly inconvenient > about Ada IO is the fact that it does not offer the convenience > and simplicity of things like C's printf or the richer IO > facilities in PL/1 and FORTRAN. Formatting a page of output, or > even printing a series of variables and descriptive information > for debugging purposes is a real pain in Ada because of the need > to use numerous simple calls. > > Unfortunately there is no easy way to get around this limitation. > Within limits you can synthesize a printf type mechanism by > defining a bunch of overloaded IO routines [at the cost of a > combinatorial explosion.] > > Likewise, you could build an IO package using "union types" > synthesized out of variant records and unchecked conversion, but > this is dangerous and inconvenient.... So, we are pretty > much stuck with a cumbersome IO mechanism.... > > Jerry Rudisin Not so! These particular options don't come close to exhausting the possibilities of Ada's definitional features. I offer the info-ada community an exercise: Devise a set of package definitions (generic and otherwise) so that, with appropriate context clauses and generic instantiations, the user can write the following calls, with meanings as given in the comments that follow them. PUT( "X = " & X & ", Y = " & Y); -- As in Pascal's write('X = ', X, ', Y = ', Y). X and Y may have -- any combination of type STRING, CHARACTER, or any integer, -- enumeration, and floating point types. At most one generic -- instantiation per type to be output is required (no combinatorial -- explosion allowed). PUT( +X & Y & Z); -- As in Pascal's write(X,Y,Z). This example is a hint: PUT(X&Y&Z) -- won't work unless X is type STRING or CHARACTER! (Mumble). PUT( "X = " & FMT(X,3) & ", Y = " & FMT(Y,11,4) ); -- As in Pascal's write('X = ',X:3,'Y = ',Y:11:4). The Ada is not as -- concise as the Pascal. See the discussion below under ``Pet -- Peeves'' Well, you get the idea. Now let's turn to C. Change the exercise above to work instead for the following example. PUT("X = %d, Y = %d", +X & Y ); -- As in printf("X = %d, Y = %d", X,Y); Unfortunately, we can't use the same tricks for input; so it goes. PET PEEVES The examples above uncover some of my own favorite problems with Ada. First, there is the rule 4.3(7) (``The type of an aggregate must be determinable solely from the context in which [it] appears, excluding the aggregate itself, but using the fact that this type must be composite....''). This makes it impossible to set things up so that I can write, for example, PUT( "X = " & (X,3) & ", Y = " & (Y,11,4) ); because I could not distinguish the type STRING (also a composite type) from whatever the types of the aggregates are. (Exercise: If 4.3(7) were gone, and the compiler were free to use the contents of an aggregate to disambiguate its type, what definitions would I need to make this last statement work as intended?) There is no technical justification for 4.3(7). It was intended, in part, to simplify overload resolution. It doesn't significantly simplify any of the type-checking/overload resolving schemes I know (indeed, it complicates some), and I've never understood why anyone thought it would. Also, it was intended to ``avoid confusing the programmer with surprising resolutions.'' However, one would expect programmers to be surprised by AMBIGUITY, not by its lack. They write something, expecting it to mean a particular thing, and if that was, in fact, its only possible meaning, they are not surprised that it works. Besides, 4.3(7) is COMPLEX. Overloading would be better understood if the rule were closer to ``It is an error for there to be more than one possible legal interpretation for a complete context.'' There are some surprises lurking here--places where resolutions are possible where one wouldn't have thought it or vice-versa--but they are mostly harmless pathologies with which to amuse idle language lawyers. I could also have cleaned up the FMT notation if it were possible to define more operators. For example: PUT( "X = " & X::3 & ", Y = " & Y::11::4 ); Exercise: What definitions are needed to make THIS work as intended, assuming "::" is a definable multiplying_operator? Simplicity may have been the reason for limiting the set of operators; I'm not sure. I have reason to believe, however, that certain other members of the Ada Design Team have had second thoughts on the matter, which is something, at least. Paul Hilfinger