Path: utzoo!attcan!uunet!lll-winken!lll-tis!mordor!joyce!ames!amdcad!sun!quintus!ok From: ok@quintus.uucp (Richard A. O'Keefe) Newsgroups: comp.lang.misc Subject: Re: Third public review of X3J11 C Message-ID: <350@quintus.UUCP> Date: 3 Sep 88 09:09:35 GMT References: <8365@smoke.ARPA> <225800053@uxe.cso.uiuc.edu> <8374@smoke.ARPA> <340@quintus.UUCP> <910@l.cc.purdue.edu> Sender: news@quintus.UUCP Reply-To: ok@quintus.UUCP (Richard A. O'Keefe) Organization: Quintus Computer Systems, Inc. Lines: 109 In article <910@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes: >It is not surprising that we do not always notice the same things. The first >thing I notice about a computer is what its instructions can do, and how >convenient it is to juggle the quantities (to me a quantity is anything, not >just a number) around. When I see a language, the corresponding question is >whether the designers have provided a way for me to use the hardware instruc- >tions, and how easy and convenient it is for me to do that. > >Consequently, the first thing to strike me about PL/I is that the insertion of >the hardware instructions the gurus did not consider in their infinite wisdom >worthy of including in the language is forced to be in the same clumsy form >which discourages the use of assembler language. That the language designers >do not consider this problem important is, I believe, the major problem in >producing efficient semi-portable software. I'm sorry, I still don't understand. PL/I doesn't include ANY hardware instructions in the language (PL/I runs on 370s, B6700s, and Multics, which don't share a word-length, still less an instruction, plus quite a few other machines). It is worth distinguishing between a language and its implementation. The PL/I *language* permits the the declaration of integers with any (fixed) number of bits via DECLARE MY_INT BINARY FIXED PRECISION(NBR_OF_BITS); So, if you need 70-bit integers, do DECLARE (I,J,K) FIXED(69); /* + 1 sign bit */ A particular PL/I *implementation* may restrict this, in which case blame the *implementation*, not the *language*. The PL/I *language* also provides the BIT(N) family of data types, and operations on them, and conversion between FIXED(N) and BIT(N) is straightfoward. So the operations Herman Rubin requests: >long long integers (at least two more bits than the exponent in a double) >Boolean operations and additions on such are already supported by the PL/I *language* (though not, perhaps, in a particular implementation). The other operations: >packing and unpacking of doubles into (exponent, mantissa), the mantissa > being a long long integer are not directly supported (converting a FLOAT to BIT(N) is done by first converting the FLOAT to FIXED), but the UNSPEC function can be used for that. For example, suppose you have a 64-bit IEEE float declared as DECLARE IEEE64 BINARY FLOAT PRECISION(52); and want to get at the sign, exponent, and significand. DECLARE S BIT(1), E BIT(11), M BIT(52), HACK BIT(64); HACK = BIT(IEEE64); /* get at the raw bits */ S = SUBSTR(HACK, 1, 1); /* sign */ E = SUBSTR(HACK, 2, 11); /* biassed exponent */ M = SUBSTR(HACK, 12, 52); /* significand */ I repeat, a particular implementation might not allow this (shame), and if it is allowed, it may be woefully inefficient, but the *LANGUAGE* permits pretty direct expression of each of Rubin's examples. A brief look through an MC68k manual suggests to me that the only 68k instructions which couldn't be accessed quite directly from a smart PL/I compiler are exchange, swap register halves, test and set, rotates, and simultaneous quotient and remainder from a divide. I haven't got an up-to-date PL/I manual, so perhaps it has got a ROTATE() function these days. As for simulatenous quotient and remainder, a peephole optimiser which can't convert Q = DEND / DOR; R = MOD(DEND, DOR); into the appropriate instruction just isn't trying. (I have to admit that the NS32k has two sets of integer divide instructions, and I do not see how to get at the other set. If PL/I were extended with the Common Lisp division functions...) I repeat from my previous posting that I have no desire to defend PL/I; it is an *awful* language. But it is less vulnerable to the charge of building in a limited set of instructions than most. (It can even get at the VAX EPOLY instruction, though the language predates the VAX.) >What do you think the reaction of HLL users would be if you required them >to write addint(x,y) for x+y if one wanted to add the integers x and y? Lisp users have written (PLUS X Y) for years, and you're talking to someone whose preferred notation is plus(Addend, Augend, Sum) (:-). _My_ definition of a HLL is one where I don't have to worry about storage management. >One point concerning the above. Standard mathematical operations can produce >more than one result. A simple example is division, with quotient and >remainder. Another example is that one frequently wants both the sine and >cosine; it is only about 30% more expensive to produce both of them simul- >taneously than to produce one. I can give other examples. Have you met POP-2? (Or its current incarnation, Poplog.) The Pop view is that an infix operator is just syntactic sugar for a function call, so x+y; x,y,+; +(x,y); x, y.+; are merely notational variants. You can declare your own operators. It has a function which yields quotient and remainder; I can never remember which result is which, but let's say it's dividend // divisor -> quotient -> remainder; Mesa will let you do something like [quo,rem] := divide[dend,dor]; *Real* high-level-languages (that is, languages which, unlike C, Pascal, Fortran, Modula-2, &c, are not very thinly disguised assembler) let you do things like let (quo,rem) = div(dend,dor) in Why functions with multiple results haven't caught on in programming languages generally I don't know (unless it is the idea that function results have something to do with registers: it's not that long since C acquired the ability to return records).