Barry_Cornelius@durham.ac.UK (06/27/88)
I thank Gernot Heiser for his comments (24Jun at 0812GMT) on my description of type changes in Modula-2. I essentially agree with Gernot. I submitted a reasonably in-depth analysis of the problem over VAL with INTEGERs to "Modus Quarterly" last September --- it got accepted but MQ hasn't appeared for a long time. (* Insert an appropriate e-mail smile/groan symbol at this point *) My article also attempted an analysis of the definitions of ORD and VAL with subrange types. The rest of this message contains the article. == 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 == Problems with the Definitions of ORD and VAL Issue 2: 1st September 1987 Barry Cornelius Computer Science Subject Group School of Engineering and Applied Science University of Durham Durham DH1 3LE England 1. Introduction The Modula-2 Report defines ORD(x) by: ordinal number (of type CARDINAL) of x in the set of values defined by type T of x. T is any enumeration type, CHAR, INTEGER, or CARDINAL. and defines VAL(T,x) by: 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 of type T. However, there are difficulties with these definitions when T is a subrange type or is the type INTEGER. It is the aim of this paper to explain these difficulties. 2. Terminology The terms "whole-number-type" and "exception" are used in this paper. By a "whole-number-type" we mean an integer or cardinal type. (We speak of "a" cardinal type in case there is more than one.) By an "exception" we mean a run-time event beyond which the semantics of the program is undefined. (Implementations may produce a warning on an exception, provide some non-standard recovery or just continue processing.) The above definitions are taken from the paper "Type Conversions in Modula-2" by Brian Wichmann ("MODUS Quarterly" Issue 6, pp. 21-24). 3. Use of ORD with Subrange types Given: TYPE months=[1..12]; lengths=[28..31]; VAR m:months; n:lengths; ... m:= 1; n:= 28; what is the value of ORD(n)? Some have argued that ORD(n) should deliver 0 because the value of n is the first value in the set of values of the type of n. However, this interpretation would cause difficulties for calls like ORD(n-1) and ORD(n+m). It would also mean that the ordinal number of a value changes depending on the subrange that is chosen. Instead the value of ORD(n) is 28. This is because of the following reasons. In general, the parameter to ORD is an expression. Now, any operand in an expression which is a variable of a subrange type is treated as if it were of the host type of the subrange type. Thus, the n in ORD(n) is considered to be of type CARDINAL and so ORD(n) has the value 28. If this approach is adopted then all the problems disappear. Pascal does it in this way --- section 6.7.1 of the ISO Pascal Standard says: Any factor whose type is S, where S is a subrange of T, shall be treated as of type T. 4. Use of VAL with Subrange types Given the types: TYPE day=(sun, mon, tue, wed, thu, fri, sat); work=[mon..fri]; then there is probably no disagreement that VAL(day,1) has the value mon. But how about VAL(work,1)? It might be argued that VAL ought to be illegal when T is a subrange type because Wirth's definition of VAL states that "T is any enumeration type, or CHAR, INTEGER, or CARDINAL" and thus subrange types are not included. However, I guess most people would argue that this was not intended. Although some would argue that VAL(work,1) ought to have the value tue, I believe that VAL(work,1) also has the value mon. Recall that VAL(T,x) is defined as "the value with ordinal number x and with type T". Now, the ordinal number of the value mon is 1 and mon is also a value of the type work. Hence, it satisfies the definition. Note that the condition VAL(T,ORD(x))=x also holds. From this, it follows that VAL(work,0) should lead to an exception since there is no value of the type work that has ordinal number 0. 5. Use of ORD and VAL with the type INTEGER What is the value of ORD(-1)? There seems to be (at least) four possible answers: (a) -MIN(INTEGER)-1 (b) -1 (c) 1 (d) an exception I'll look at each of these in turn. 5.1 ORD(-1) has the value -MIN(INTEGER)-1 The Modula-2 Report states that ORD delivers a value of type CARDINAL. The way to map all the INTEGER values onto CARDINAL values is as follows: ORD(-32768) = 0 ... ORD( -1) = 32767 ORD( 0) = 32768 ORD( 1) = 32769 ... ORD( 32767) = 65535 Here I have assumed particular values for MIN(INTEGER) and MAX(INTEGER) to help me understand things! There are problems with this proposal: (a) It means that the value of ORD(1) depends on its context. It may be equal to 1 or 32769 depending on whether an INTEGER or CARDINAL value is expected. (b) If c is a CARDINAL variable having the value 1 then VAL(INTEGER,c) would have the value -32767. Thus, to convert a numerical value from CARDINAL to INTEGER, one would need to use something like VAL(INTEGER,c+32768). (c) It assumes that the number of values of type INTEGER is not more than the number of values of type CARDINAL. (d) It will need some amendment to cope with the ordinal numbers of the type LONGINT. 5.2 ORD(-1) has the value -1 Section 6.4.2.2 of the ISO Pascal Standard states that "the ordinal number of a value of integer-type shall be the value itself". Hence, in Pascal, ORD(-1) has the value -1. The major difficulty with using this in Modula-2 is that, in Modula-2, ORD delivers a CARDINAL. Altering ORD to produce an INTEGER would cause problems for examples like ORD(MAX(CARDINAL)). 5.3 ORD(-1) has the value 1 One obvious way of avoiding the negative numbers is to say that "the ordinal number of a value of the type INTEGER shall be its absolute value". This, of course, leads to a problem with VAL(INTEGER,1). Is this equal to -1 or 1? 5.4 ORD(-1) leads to an exception On behalf of the BSI's Modula-2 Working Group, Don Ward and I have recently been considering the formal definition of Modula-2's standard procedures. We propose that: (a) ORD delivers a CARDINAL (b) when n is of some whole-number-type, ORD(n) has the same numerical value as n, no matter what the type of n is provided that the numerical value of n belongs to the type CARDINAL (c) when n is of some whole-number-type, ORD(n) leads to an exception if the numerical value of n is not a value of the type CARDINAL This proposal is written in terms of "whole-number-type". Thus, it is applicable not only when n is of type INTEGER but also when n is, say, of the type LONGINT.
alan@pdn.UUCP (Alan Lovejoy) (06/28/88)
In article <INFO-M2%88062707565110@UCF1VM> Info-Modula2 Distribution List <INFO-M2%UCF1VM.bitnet@jade.berkeley.edu> writes:
/On behalf of the BSI's Modula-2 Working Group, Don Ward and I have
/recently been considering the formal definition of Modula-2's
/standard procedures. We propose that:
/
/(a) ORD delivers a CARDINAL
/
/(b) when n is of some whole-number-type, ORD(n) has the same
/> numerical value as n, no matter what the type of n is provided
/> that the numerical value of n belongs to the type CARDINAL
/
/(c) when n is of some whole-number-type, ORD(n) leads to an
/> exception if the numerical value of n is not a value of the
/> type CARDINAL
Why not define ORD(aValueOfIntType) to be CARDINAL(aValueOfIntType)?
That is, a meaning-preserving coercion into type CARDINAL? That way,
you could just get rid of ORD altogether! Didn't the BSI/ISO committee
propose doing just that a while ago? I seem to remember reading some
such proposal in Modus Quarterly.
For ORD(-1) (that is, CARDINAL(-1)) that would mean an exception, since
there is no CARDINAL value that corresponds to -1 (by definition).
--
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!
nagler%olsen@unizh.UUCP (Robert Nagler) (06/30/88)
Why not define ORD(aValueOfIntType) to be CARDINAL(aValueOfIntType)? That is, a meaning-preserving coercion into type CARDINAL? That way, you could just get rid of ORD altogether! Pardon me, but what does the term "meaning-preserving coercion" denote? As far as I understand type coercions in other languages, I believe the current semantics are "meaning-preserving", that is, they preserve the meaning of the memory and that is all. You cannot get rid of ORD, because it returns the "ordinal" value in terms of a type CARDINAL. The type conversion CARDINAL merely subverts the type checking mechanism. I know that I am a bad boy, but sometimes I need to do things like: bitset := BITSET( CARDINAL( bitset ) DIV 100H ); This is quite a useful operation in certain types of system programming. Rob PS. I've been wondering what would happen if all this talk about designing Modula-2-rev-Q were translated into energy which could be used to develop a portable public domain language environment.
alan@pdn.UUCP (Alan Lovejoy) (07/04/88)
In article <8806300811.AA00246@klaus.olsen.uucp> Info-Modula2 Distribution List <INFO-M2%UCF1VM.bitnet@jade.berkeley.edu> writes: >Pardon me, but what does the term "meaning-preserving coercion" denote? >As far as I understand type coercions in other languages, I believe the >current semantics are "meaning-preserving", that is, they preserve the >meaning of the memory and that is all. You cannot get rid of ORD, because >it returns the "ordinal" value in terms of a type CARDINAL. The type >conversion CARDINAL merely subverts the type checking mechanism. I know I am sorry if the terminology I used confused you (or anyone). And it did confuse you. The term coercion was used imprecisely. In the current language, CARDINAL(-1) would have the value 65535 on most systems. This is a "bit-preserving type coercion" in the terminology I usually use. What the BSI committee proposed (a previous posting indicates they now have a new proposal), was that CARDINAL(3.0) become a "meaning-preserving type conversion", which in the case of the example would have the value 3. The new proposal is that the syntax for this type of conversion be CONVERT(CARDINAL, 3.0). They want to avoid using VAL for this since may compilers use it as a synonym for the bit-preserving type transfers (even though Wirth's books define it as a meaning-preserving conversion). Perhaps they could use VALUE, instead of CONVERT or VAL. Although I liked the original proposal better (just using the type name). The proposed (and ISO accepted) syntax for bit-preserving transfers is CAST(CARDINAL, -1). CAST must be imported from SYSTEM. Although bit-preserving type transfers are necessary for systems programming, it is unfortunate that in the current language they are so easily accomplished while the far safer and even more important meaning preserving conversions are only haphazardly supported. For example, there is no standard way to convert between long and short types, INTEGERs and CARDINALs, or REALS to INTEGERS (TRUNC returns type CARDINAL, for some strange reason). Even worse, the syntax for each such conversion that is supported is different for each case! This makes it impossible to write portable code that converts one type into an equivalent value of another type when the types involved may change from system to system, because the types being converted are improperly and unnecessarily bound to the syntax of the conversion operator. This should be fixed. -- 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!
wex@SW.MCC.COM (Alan Wexelblat) (07/05/88)
> The proposed (and ISO accepted) syntax for bit-preserving transfers is > CAST(CARDINAL, -1). CAST must be imported from SYSTEM. This still leaves me wondering what a "meaning-preserving" conversion is for CAST(CARDINAL, -1) What value would you expect to get back? --Alan Wexelblat ARPA: WEX@MCC.COM UUCP: {harvard, gatech, pyramid, &c.}!sally!im4u!milano!wex "How do we measure the distance between Ken Kesey and Carlos Lehder?" -- Hunter Thompson
alan@pdn.UUCP (Alan Lovejoy) (07/06/88)
In article <8807051419.AA05623@banzai-inst.sw.mcc.com> Info-Modula2 Distribution List <INFO-M2%UCF1VM.bitnet@jade.berkeley.edu> writes: >This still leaves me wondering what a "meaning-preserving" conversion is for > CAST(CARDINAL, -1) >What value would you expect to get back? >--Alan Wexelblat >ARPA: WEX@MCC.COM >UUCP: {harvard, gatech, pyramid, &c.}!sally!im4u!milano!wex According to Barry Cornelius's posting on the subject, the BSI proposal currently on the table is "CONVERT(CARDINAL, -1)" as the syntax for a "meaning-preserving" conversion. In this case the "value" is an exception. What an "exception" is, is formally undefined. It is expected to be either a no-op, a program abort or a trap to a debugging tool. -- 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!
claudio@forty2.UUCP (Claudio Nieder) (07/08/88)
In article <8807051419.AA05623@banzai-inst.sw.mcc.com> Info-Modula2 Distribution List <INFO-M2%UCF1VM.bitnet@jade.berkeley.edu> writes: >> The proposed (and ISO accepted) syntax for bit-preserving transfers is |> CAST(CARDINAL, -1). CAST must be imported from SYSTEM. | |This still leaves me wondering what a "meaning-preserving" conversion is for | CAST(CARDINAL, -1) | |What value would you expect to get back? First let me assume that by meaning-preserving "CAST" you mean the conversion done with either CONVERT(CARDINAL,-1) or simply CARDINAL(-1) presented in an earlier posting. The M2Amiga compiler treats this as an error, similar as if you would write: MODULE t; VAR c:CARDINAL; BEGIN c:=-1; END t. It is not possible to transform -1 into a CARDINAL number and preserv its meaning/value. That's only possible if the target type contains that number. E.g. it is possible to write in M2Amiga: MODULE t; VAR c:CARDINAL; r:REAL; BEGIN c:=1; r:=REAL(c); END t. and r will get the value 1.0 .