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!apluslalan@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