aplusl@ethz.UUCP (Albert Meier) (07/02/88)
Expires: Sender: Reply-To: aplusl@bernina.UUCP (Albert Meier) Followup-To: Distribution: comp.lang.modula2 Organization: ETH Zuerich, Switzerland Keywords: Here is now the exact proposal from Pat Terry (SA) and me (CH). We have been asked to post it. As mentioned before for Switzerland it is the second choice (the third has been decided in Nice, the first choice is reconsidering the BSI proposal voted against in Nice). Pat has no access to Usenet but he kindly greets you all. Here it comes: To: Persons interested in type conversions in Modula-2 From: Pat Terry, Computer Science, Rhodes University, GRAHAMSTOWN 6140 _______________________________________________________________________________________________________________ The Nice ISO standardisation meeting adopted a proposal of mine concerning "safe" type conversions, I suspect reluctantly, and with good reason. The proposal was motivated mainly by a desire to clear a log-jam, and with an eye on what was about to follow (the discussion on the status of ORD, TRUNC and FLOAT). Albert Meier and I would like to make a compromise suggestion. It is of interest to review the various proposals made for safe conversions. The position in PIM, I believe, can be summarised in the following table, which omits the potential complications from range errors. To convert an Expression of type Integer Cardinal Real Longreal Char Enum To a result of type Integer - VAL * * * * Cardinal VAL/ORD - TRUNC * ORD ORD Real * FLOAT - * * * Longreal * * * - * * Char * VAL/CHR * * - * Enum * VAL * * * - Here the * entries represent "no direct one-step conversion" and the - entries represent "no conversion needed". "Enum" means any enumerated type, including BOOLEAN. In fact, I am not certain how one converts directly from an integer to a cardinal. A close reading of PIM suggests that ORD is used, but I have seen VAL advocated, and I have seen compilers do strange things here too. Another viewpoint is that ORD(MIN(INTEGER)) should return 0, but this is really rather ludicrous, and I do not think anyone would take this seriously. One is struck with the sparseness of the table. Some conversions are really horrible, for example from integer to real. Presumably one really needs code like IF I > 0 THEN R := FLOAT(ORD(I)) ELSE R := - FLOAT(ORD(ABS(I)) END which would be very tiresome if complicated compound expressions were needed. One gets the distinct impression that the implementors of the original compilers never have any need for writing any number-crunching programs - or indeed, any that use REAL at all. One could level the same criticism at their total disregard for COMPLEX, but that is a rather different issue. When I teach students here they are completely amazed at the difficulty which using REAL seems to present. The BSI proposal for safe conversions, as I can see it (stripped of the LONGCARD, LONGINT, SHORTINT etc baggage which I think we can agree is a side issue here), can be summarised in the following table. To convert an Expression of type Integer Cardinal Real Longreal Char Enum To a result of type Integer - INTEGER INTEGER INTEGER * * Cardinal CARDINAL - CARDINAL CARDINAL CARDINAL CARDINAL Real REAL REAL - REAL * * Longreal LONGREAL LONGREAL LONGREAL - * * Char * CHAR * * - * Enum * DAYS * * * - The proposal adopted at the Nice meeting can be summarised as follows To convert an Expression of type Integer Cardinal Real Longreal Char Enum To a result of type Integer - CONVERT CONVERT CONVERT * * Cardinal CONVERT - CONVERT/TRUNC CONVERT CONVERT/ORD CONVERT/ORD Real CONVERT CONVERT/FLOAT - CONVERT * * Longreal CONVERT CONVERT CONVERT - * * Char * CONVERT/CHR * * - * Enum * CONVERT * * * - The objection to this is aesthetic - it is very clumsy to use CONVERT(T,x) when a nice simple function would look better. The objections to the BSI proposal are really that they introduce new semantics into old syntax. The argument in favour of ORD, TRUNC and CHR is that they are familiar and already part of the language. The point need to be made that the "standard" functions in Modula-2 are mostly highly non-standard, in that many of them are in fact generic. Once this is accepted, there seems no reason why similar functions should not be as generic as ORD (which maps "any" ordinal type to CARDINAL), for example, and why FLOAT should not be able to map "any" numerical value to REAL. Admittedly, REAL would be a better name than FLOAT, but that's history that we cannot rewrite. The suggestion Albert and I would like to make is summarised in the following table. It introduces three new pervasive identifiers INT, CARD and LFLOAT. To convert an Expression of type Integer Cardinal Real Longreal Char Enum To a result of type Integer - INT INT INT INT INT Cardinal CARD/ORD - CARD/TRUNC CARD CARD/ORD CARD/ORD Real FLOAT FLOAT - FLOAT * * Longreal LFLOAT LFLOAT LFLOAT - * * Char CHR CHR * * - * Enum CONVERT CONVERT * * * - CHR, TRUNC and ORD are retained for historical reasons. The matrix is now symmetric, and the usage of CONVERT would probably be minimal in practice. CARD could be dispensed with, and ORD used throughout, but CARD and INT would make a nice pair, with the intent fairly obvious. There is a lurking problem in that if an implementation wants to have SYSTEM.LONGCARD or SYSTEM.SHORTINT or whatever, this seems to require a further plethora of names. However, we could still demand that CARD, INT, FLOAT, LFLOAT apply to arguments of any of these types, and would need only to introduce LCARD, LINT, SCARD, SINT and so on. SSS N N V V SNV SWISS STANDARDIZATION BODY S NN N V V 149/UK2 Programming Languages SSS N N N V V Chairman Albert Meier, CH-8906 Bonstetten S N NN V V . E-mail aplusl@ifi.ethz.(ch/UUCP) SSS N N V ...mcvax!cernvax!ethz!aplusl
alan@pdn.UUCP (Alan Lovejoy) (07/04/88)
In article <491@ethz.UUCP> aplusl@ethz.UUCP (Albert Meier) writes: >The proposal adopted at the Nice meeting can be summarised as follows > > To convert an Expression of type > > Integer Cardinal Real Longreal Char Enum > To a result > of type > > Integer - CONVERT CONVERT CONVERT * * > > Cardinal CONVERT - CONVERT/TRUNC CONVERT CONVERT/ORD >CONVERT/ORD > > Real CONVERT CONVERT/FLOAT - CONVERT * * > > Longreal CONVERT CONVERT CONVERT - * * > > Char * CONVERT/CHR * * - * > > Enum * CONVERT * * * - >[Another suggestion:] > To convert an Expression of type > > Integer Cardinal Real Longreal Char Enum > To a result > of type > > Integer - INT INT INT INT INT > > Cardinal CARD/ORD - CARD/TRUNC CARD CARD/ORD CARD/ORD > > Real FLOAT FLOAT - FLOAT * * > > Longreal LFLOAT LFLOAT LFLOAT - * * > > Char CHR CHR * * - * > > Enum CONVERT CONVERT * * * - I have several objections to both of these porposals: 1) What about subrange types? Simply changing one of the bounds could make such types change from long to short (or short to long), or from INTEGER to CARDINAL. The following code may break: TYPE SubRange1 = [min1..max1]; SubRange2 = [min2..max2]; ... aValueOfSubRange1 := INT(aValueOfSubRange2); This code is not portable because it hard-codes the fact that SubRange1 is an INTEGER subrange and that SubRange2 is a CARDINAL subrange. If the values of min1, max1, min2 and max2 are system-dependent values, then the code will certainly be busted as it is ported from system to system. On the other hand, if the bounds constants are application dependent, then the code can not be made generic to all applications. Better would be the following: aValueOfSubRange1 := SubRange1(aValueOfSubRange2); -- or even -- aValueOfSubRange1 := VALUE(aValueOfSubRange2); Now the code is valid as long as a meaning-preserving conversion is possible between the two types. It the two types are the same, then it is simply a null operation. If the right-hand-side value is out of range of the SubRange1, then a run-time exception occurs. 2) The proposals are too complicated with exceptions and different keywords for a single operation: meaning-preserving conversion. Modula-2 is getting too many built-in types to even think about having a different conversion operator for each possible combination. Keep it simple, stupid! Quick, can you remember which conversions between the basic types are legal and illegal in the proposals quoted above? -- Alan Lovejoy; alan@pdn; 813-530-8241; Paradyne Corporation: Largo, Florida. Disclaimer: Do not confuse my views with the official views of Paradyne Corporation (regardless of how confusing those views may be). Motto: Never put off to run-time what you can do at compile-time!
mrys@ethz.UUCP (Michael Rys) (07/06/88)
On the Ceres workstation developped at the Inst. of Inf. ETH the standard Modula-2 Compiler defines CARDINAL as subrange of INTEGER, for the range [MAX(INTEGER)..MAX(CARDINALold)] and further you may use then LONGINT. In the manual is written that CARDINAL is obsolete and should therefore be replaced by INTEGER or LONGINT wherever possible. Cheers...Michael uucp: mrys@ethz.uucp IPSANet : mrys@ipsaint
aplusl@ethz.UUCP (Albert Meier) (07/07/88)
In article <500@ethz.UUCP> mrys@bernina.UUCP (Michael Rys) writes: >On the Ceres workstation developped at the Inst. of Inf. ETH the >standard Modula-2 Compiler defines CARDINAL as subrange of INTEGER, >for the range [MAX(INTEGER)..MAX(CARDINALold)] and further you may use >then LONGINT. In the manual is written that CARDINAL is obsolete and >should therefore be replaced by INTEGER or LONGINT wherever possible. As far as I remember we decided in Nice to solve this problem with the help of 3 constants "z1", "z2" and "z3" that define the bounds of the basic numeric types. For the ETH single pass compiler, that is also used on the Ceres this would meen z1=z2<z3, for most other compilers it means z1<z2<z3. SSS N N V V SNV SWISS STANDARDIZATION BODY S NN N V V 149/UK2 Programming Languages SSS N N N V V Chairman Albert Meier, CH-8906 Bonstetten S N NN V V . E-mail aplusl@ifi.ethz.(ch/UUCP) SSS N N V ...mcvax!cernvax!ethz!aplusl