[comp.lang.modula2] type changes

Barry_Cornelius@durham.ac.UK (06/17/88)

 Nathan Bohlmann and Keith Campbell have recently communicated
 about how type changes are performed in Modula-2.   It is, in fact,
 possible to distinguish between two different kinds of type change
 in Modula-2:
 o  Given a value of one type, the language specifies an appropriate
    value of another type.  This kind of type change will be referred
    to as a coercion.
 o  Given a value of one type, its internal representation is interpreted
    as if it were that of another type.  This kind of type change will
    be referred to as a cast.
 Often an implementation will have to generate run-time code
 in order to perform a coercion, whereas a cast requires no such
 overhead.  Obviously, casts should be avoided if a program is to be
 portable.  Sometimes coercions and casts are referred to as
 safe and unsafe conversions.

 In Modula-2, there are five standard functions
 which perform coercions; they are CHR, ORD, FLOAT, TRUNC and VAL.

 Section 12 of the Modula-2 Report includes details of how casts
 can be performed in Modula-2.  A type identifier T can be used
    ``as a name denoting the type transfer from the type
    of the operand to the type T.  ... such functions
    ... involve no explicit conversion instructions''.
 Although it is not actually stated, implementations usually assume
 that the values of the two types occupy the same amount of storage.
 For example, suppose that this is true for the types CARDINAL
 and INTEGER and that the CARDINAL variable c has the value
 65535, then the expression INTEGER(c) is of type INTEGER
 and has a value which is dependent on the internal representations of
 the types CARDINAL and INTEGER.  This value is often -1
 on a 16-bit computer and 65535 on a 32-bit computer.

 Programmers frequently use expressions like INTEGER(c)
 in order to convert a value of type CARDINAL into one of type
 INTEGER.  However, this practice ought to be avoided
 since it only works if the types CARDINAL and INTEGER
 have the same representation for the possible values of c.
 Although this is likely to be the case, programmers ought to use
 VAL(INTEGER,c) which is guaranteed to work for appropriate values of c.

 It is interesting to note that most of the problems concerning
 type changes are not present in the language Oberon.  In particular,
 the type CARDINAL has been removed and the types LONGREAL, REAL,
 LONGINT, INTEGER and SHORTINT are compatible with each other.
 Wirth also considers it inappropriate to define for Oberon
 a mechanism for performing casts.  He describes Modula-2's
 type transfer functions as a ``a particularly seducing trap''!
 ==
 Barry Cornelius
 ==
 Address:
    Computer Science Group, School of Engineering and Applied Science,
    University of Durham, Durham, DH1 3LE, England
 Telephone:
    My office: Durham (091 or +44 91) 374 2638
    Secretary: Durham (091 or +44 91) 374 2630
    Fax:       Durham (091 or +44 91) 374 3740
 Electronic Mail Addresses:
    JANET:       Barry_Cornelius@uk.ac.dur.mts
    Internet:    Barry_Cornelius%mts.dur.ac.uk@cunyvm.cuny.edu
    UUCP:        ...ukc!cs.nott.ac.uk!bjc
    BITNET/EARN: Barry_Cornelius%DUR.MTS@AC.UK

heiser@ethz.UUCP (Gernot Heiser) (06/24/88)

In article <INFO-M2%88061707562183@UCF1VM> Info-Modula2 Distribution List <INFO-M2%UCF1VM.bitnet@jade.berkeley.edu> writes:
>
> Programmers frequently use expressions like INTEGER(c)
> in order to convert a value of type CARDINAL into one of type
> INTEGER.  However, this practice ought to be avoided
> since it only works if the types CARDINAL and INTEGER
> have the same representation for the possible values of c.
> Although this is likely to be the case, programmers ought to use
> VAL(INTEGER,c) which is guaranteed to work for appropriate values of c.

Sorry for having to contradict here: There is nothing in the  report (as I read
it)  that  supports the claim  that VAL(INTEGER,c) or VAL(CARDINAL,i) will work
"as intended" although it  _does_ work on  all compilers I  know (at  least all
those that implement VAL  more or less  according  to  the  report). In  fact a
strict interpretation of the report implies the opposite.

Quoting from PIM2, ed3, p 162:
	"ORD(x)		ordinal number (of type CARDINAL) of x in the set of
			values defined by type T of x. T is an enumeration type,
			CHAR, INTEGER, or CARDINAL.

	"VAL(T,x)	the value with ordinal number x and with type T. T is
			any enumeration type, or CHAR, INTEGER, or CARDINAL.
			VAL(T,ORD(x)) = x, if x is of type T."

In  other words,  VAL  with a CARDINAL  argument  is  the inverse  of  ORD. The
question is,  what  is ORD(i)  (i being  INTEGER)? It cannot  be the   CARDINAL
representation of the number whose INTEGER representation  is i, since  not all
numbers that have an INTEGER  representation have a CARDINAL representation too
(namely the negative INTEGERs). So, unless one assumes  that ORD is not defined
for all INTEGERs (and there is no  indication in the  report that would support
such an assumption) and  unless one is prepared  to treat INTEGER as  a special
case (different from  enumerationes, CHAR and  CARDINAL, and again there is  no
indication to support that in the report) one has to assume that ORD(MinInt)=0,
ORD(MinInt+1) = 1, ORD(MaxInt)=MaxCard  etc. Consequently,  VAL(INTEGER,c) does
not at all work as intended! (For all other types VAL(T,x) is indeed the "safe"
conversion.)

I agree, that's nonsensical, however that's  what the report says. Fortunately,
no compiler (that I know of) does  it  that way, but assuming VAL(INTEGER,c) to
be the "safe" conversion from CARDINAL  to INTEGER is  relying on all compilers
violating the language report.

Note that Wirth in his later compilers solves the problem in his characteristic
way:  he gives VAL(T,x)  the semantics  that T(x) used  to have  and completely
eliminates "save" type transfers.

> ==
> Barry Cornelius

-- 
Gernot Heiser <heiser@iis.UUCP> Phone:       +41 1/256 23 48
Integrated Systems Laboratory   CSNET/ARPA:  heiser%ifi.ethz.ch@relay.cs.net
ETH Zuerich                     EARN/BITNET: GRIDFILE@CZHETH5A
CH-8092 Zuerich, Switzerland    EUNET/UUCP:  {uunet,mcvax,...}!iis!heiser