From hosking at cs.purdue.edu Fri Jan 1 21:30:42 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 1 Jan 2010 15:30:42 -0500 Subject: [M3devel] Fwd: [CM3] #1080: CVSUPD server hangs if used with -C option In-Reply-To: <20091229184748.frhga784gkk4cosg@mail.elegosoft.com> References: <20091229184748.frhga784gkk4cosg@mail.elegosoft.com> Message-ID: <726BCE28-8561-40BF-BFBD-F96EC4151B50@cs.purdue.edu> What does -C do? On 29 Dec 2009, at 12:47, Olaf Wagner wrote: > Any ideas? Interaction problem between threads and select? > > Olaf > > ----- Forwarded message from bugs at elego.de ----- > Date: Tue, 29 Dec 2009 16:23:23 -0000 > From: CM3 > Reply-To: CM3 > Subject: [CM3] #1080: CVSUPD server hangs if used with -C option > To: @MISSING_DOMAIN > > #1080: CVSUPD server hangs if used with -C option > -----------------------------+---------------------------------------------- > Reporter: rajeshvadivelu | Owner: wagner > Type: sw-bug | Status: new > Priority: high | Milestone: > Component: sys | Version: 5.8-RC3 > Severity: critical | Keywords: > Relnote: | Confidential: no > Org: Collabnet | Estimatedhours: 0 > Hours: 0 | Billable: 0 > Totalhours: 0 | > -----------------------------+---------------------------------------------- > Htr: > Install cvsup from cm3-bin-ws-cvsup-LINUXLIBC6-5.8.4-RC4.tgz package. > > Start the cvsupd server with -C option > > ./cvsupd -b /data/cvsupd -C 2 > > Try cvsup client to connect to the sever > > ./cvsup -g -L 2 /tmp/cvsupd.cfg > > The client connection will hang and after sometime we will get "Inactivity timeout" > > > Fix: > > > > Env: > > > -----------------------------+---------------------------------------------- > In a RHEL5 32bit box I was trying to run cvsupd server to mirror my cvs > repo. I did used cm3-bin-ws-cvsup-LINUXLIBC6-5.8.4-RC4.tgz to get the > cvsup installed. > > The server starts find and there was no issues if I start the server > without -C option. > > Starting cvsupd server without -C option > > $ ./cvsupd -b /u2/site/data/cvsupd > 2009.12.29 21:31:05 IST [6225]: CVSup server started > 2009.12.29 21:31:05 IST [6225]: Software version: 2009-08-30 21:02:46 > 2009.12.29 21:31:05 IST [6225]: Protocol version: 17.0 > 2009.12.29 21:31:05 IST [6225]: Ready to service requests > > Then I did a client request as below > > $ ./cvsup -g -L 2 /tmp/cvsupd.cfg > Parsing supfile "/tmp/cvsupd.cfg" > Connecting to myserver.com > Connected to myserver.com > Rejected by server: Access denied > Will retry at 21:37:09 > > So the request was successful and I get a valid error message at the > client. > > But when I start the server with -C option like the one as below, requests > from client are hanging and eventually getting "Inactivity timeout" after > sometime. > > $ ./cvsupd -b /u2/site/data/cvsupd -C 2 > > When ever a new client connection was made, this daemon clones another > cvsupd process and it also hangs. So none of the client request were > processed. > > Strace of the main cvsupd server process, when a new client request was > fired. > > ----------------------------------- > select(4, [3], [], [3], {0, 39000}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 1 (in [3], left {0, 553000}) > accept(3, {sa_family=AF_INET, sin_port=htons(51221), > sin_addr=inet_addr("208.75.198.60")}, [16]) = 6 > setsockopt(6, SOL_SOCKET, SO_LINGER, {onoff=1, linger=1}, 8) = 0 > setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0 > fcntl64(6, F_GETFL) = 0x2 (flags O_RDWR) > fcntl64(6, F_SETFL, O_RDWR|O_NONBLOCK) = 0 > gettimeofday({1262103026, 146476}, NULL) = 0 > open("/u2/site/data/cvsupd/cvsupd.access", O_RDONLY|O_LARGEFILE) = 7 > fstat64(7, {st_mode=S_IFREG|0755, st_size=215, ...}) = 0 > _llseek(7, 0, [0], SEEK_CUR) = 0 > fstat64(7, {st_mode=S_IFREG|0755, st_size=215, ...}) = 0 > close(7) = 0 > gettimeofday({1262103026, 147481}, NULL) = 0 > stat64("/u2/site/data/cvsupd/cvsupd.class", 0xbf809c04) = -1 ENOENT (No > such file or directory) > write(5, "\0", 1) = 1 > futex(0x91580f0, FUTEX_WAKE, 1) = 1 > futex(0x9158098, FUTEX_WAKE, 1) = 1 > futex(0x91580b8, FUTEX_WAKE, 1) = 1 > futex(0x91580bc, FUTEX_WAIT, 5, NULL) = -1 EAGAIN (Resource temporarily > unavailable) > futex(0x9158098, FUTEX_WAKE, 1) = 0 > clone(child_stack=0, > flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, > child_tidptr=0xb7f43708) = 6543 > futex(0x915a484, 0x5 /* FUTEX_??? */, 1) = 1 > futex(0x915a460, FUTEX_WAKE, 1) = 1 > futex(0x91580f0, FUTEX_WAKE, 1) = 1 > futex(0x9158098, FUTEX_WAKE, 1) = 1 > futex(0x91580b8, FUTEX_WAKE, 1) = 1 > futex(0x91580bc, FUTEX_WAIT, 7, NULL) = -1 EAGAIN (Resource temporarily > unavailable) > futex(0x9158098, FUTEX_WAKE, 1) = 0 > close(6) = 0 > accept(3, 0xbf809e44, [16]) = -1 EAGAIN (Resource temporarily > unavailable) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > ------------------------------------ > > gdb backtrace of the main cvsupd server process > > ------------------------------------ > > #0 0x00a2a402 in __kernel_vsyscall () > #1 0x0026efb1 in ___newselect_nocancel () from /lib/libc.so.6 > #2 0x00f8965b in Unix__select (nfds=4, readfds=0xb7f9df78, > writefds=0xb7f9df88, exceptfds=0xb7f9df98, timeout=0xbfed9410) at > ../src/unix/Common/UnixC.c:301 > #3 0x00f85f4b in ThreadPThread__XIOWait__CallSelect.779 (M3_Cwb5VA_nfd=4, > M3_A4bqCj_timeout=0xbfed9410) at > ../src/thread/PTHREAD/ThreadPThread.m3:900 > #4 0x00f85c7a in ThreadPThread__XIOWait (M3_BXP32l_self=0xb7f9400c, > M3_Cwb5VA_fd=3, M3_AicXUJ_read=1 '\001', > M3_CtKayy_interval=1.7976931348623157e+308, M3_AicXUJ_alertable=1 '\001') > at ../src/thread/PTHREAD/ThreadPThread.m3:936 > #5 0x00f8589d in SchedulerPosix__IOAlertWait (M3_Cwb5VA_fd=3, > M3_AicXUJ_read=1 '\001', M3_CtKayy_timeoutInterval=-1) at > ../src/thread/PTHREAD/ThreadPThread.m3:854 > #6 0x00e4b499 in TCPMisc__AcceptFrom (M3_AahksS_c=0xb7f9ca48, > M3_DoBjMZ_peer=0xbfed9970) at ../src/POSIX/TCP.m3:458 > #7 0x0807bcbf in FSServer__Run (M3_DS26rk_self=0xb7f9c9fc) at > ../src/FSServer.m3:153 > #8 0x080934fd in Main_M3 (M3_AcxOUs_mode=1) at ../src/Main.m3:336 > #9 0x00f717c8 in RTLinker__RunMainBody (M3_DjPxE3_m=0x80a11a0) at > ../src/runtime/common/RTLinker.m3:399 > #10 0x00f70b82 in RTLinker__AddUnitI (M3_DjPxE3_m=0x80a11a0) at > ../src/runtime/common/RTLinker.m3:113 > #11 0x00f70c10 in RTLinker__AddUnit (M3_DjPxE5_b=0x8090f4e) at > ../src/runtime/common/RTLinker.m3:122 > #12 0x0804db1e in main (argc=5, argv=0xbfeda124, envp=0xbfeda13c) at > _m3main.mc:4 > ------------------------------------------------ > > > strace of the cloned cvsupd process > > ----------------------------------- > > futex(0x91580bc, FUTEX_WAIT, 3, NULL > > ----------------------------------- > > gdb backtrace of the cloned cvsupd process > > ----------------------------------- > > #0 0x00a2a402 in __kernel_vsyscall () > #1 0x00320146 in pthread_cond_wait@@GLIBC_2.3.2 () from > /lib/libpthread.so.0 > #2 0x00f886e6 in ThreadPThread__pthread_cond_wait (cond=0x89c60b8, > mutex=0x89c6098) at ../src/thread/PTHREAD/ThreadPThreadC.c:326 > #3 0x00f81d9d in ThreadPThread__XWait (M3_BXP32l_self=0xb7f9400c, > M3_AYIbX3_m=0xb7f9c8d8, M3_Bl0jv4_c=0xb7f9c8f4, M3_AicXUJ_alertable=0 > '\0') at ../src/thread/PTHREAD/ThreadPThread.m3:238 > #4 0x00f821ae in Thread__Wait (M3_AYIbX3_m=0xb7f9c8d8, > M3_Bl0jv4_c=0xb7f9c8f4) at ../src/thread/PTHREAD/ThreadPThread.m3:280 > #5 0x00bd4e14 in SigHandler__ChangeState (M3_BnMAgS_d=0xb7f9c4bc, > M3_AkN0P6_state=2 '\002') at ../src/SigHandler.m3:105 > #6 0x00bd5ba6 in SigHandler__ShutDown () at ../src/SigHandler.m3:243 > #7 0x0807cbac in FSServer_M3_LINE_230.718 (L_2=0xbfed95d0) at > ../src/FSServer.m3:231 > #8 0x0807c956 in FSServer__Run (M3_DS26rk_self=0xb7f9c9fc) at > ../src/FSServer.m3:227 > #9 0x080934fd in Main_M3 (M3_AcxOUs_mode=1) at ../src/Main.m3:336 > #10 0x00f717c8 in RTLinker__RunMainBody (M3_DjPxE3_m=0x80a11a0) at > ../src/runtime/common/RTLinker.m3:399 > #11 0x00f70b82 in RTLinker__AddUnitI (M3_DjPxE3_m=0x80a11a0) at > ../src/runtime/common/RTLinker.m3:113 > #12 0x00f70c10 in RTLinker__AddUnit (M3_DjPxE5_b=0x8090f4e) at > ../src/runtime/common/RTLinker.m3:122 > #13 0x0804db1e in main (argc=5, argv=0xbfeda124, envp=0xbfeda13c) at > _m3main.mc:4 > > ------------------------------------------- > > So it looks like both the main and cloned cvsupd processes were waiting > for a response from the kernel call "__kernel_vsyscall ()". Under what > condition will this happen? Am I doing something wrong here? > > -- > Ticket URL: > CM3 > Critical Mass Modula3 Compiler > > > ----- End forwarded message ----- > > > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 1 23:56:00 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 1 Jan 2010 22:56:00 +0000 Subject: [M3devel] scope/resolution of foo in interface foo = foo(bar) In-Reply-To: <21B2F22D-C1E9-46F2-8434-4CD78DCD7E96@cs.purdue.edu> References: <20091230144007.081152474001@birch.elegosoft.com>, <21B2F22D-C1E9-46F2-8434-4CD78DCD7E96@cs.purdue.edu> Message-ID: I can understand that the name on the left isn't in scope "yet" on the right, but what is the algorithm for anyone else using IMPORT? import foo; import foo(bar); import foo(bar) as foobar; import foo(bar).T as fooT; I doubt all but the first of these are legal, but I also don't think they are very far fetched in terms of being reasonable constructs and not difficult to implement. And I'm not sure the presence of the '(' is enough disambiguation for a quick human reader or a pleasantly simply enough implementation, but maybe. All that is to say, I don't think disallowing interface foo = foo(bar) is so bad. - Jay From: hosking at cs.purdue.edu Date: Fri, 1 Jan 2010 14:43:36 -0500 To: jkrell at elego.de CC: m3commit at elegosoft.com Subject: Re: [M3commit] CVS Update: cm3 That's a bug in m3tk scope management. Probably needs a ticket in the bugs database... On 30 Dec 2009, at 15:40, Jay Krell wrote:CVSROOT: /usr/cvs Changes by: jkrell at birch. 09/12/30 15:40:06 Modified files: cm3/m3-libs/m3core/src/word/: Long.i3 Long.m3 Word.i3 Word.m3 m3makefile Added files: cm3/m3-libs/m3core/src/word/: GenWord.ig GenWord.mg Removed files: cm3/m3-libs/m3core/src/word/: Word.ig Word.mg Log message: go back to GenWord the other front end (Olivetti m3-tk) doesn't understand INTERFACE Word = Word(WordRep) END Word. but it does't understand INTERFACE Word = GenWord(WordRep) END Word. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mika at async.async.caltech.edu Sat Jan 2 00:02:23 2010 From: mika at async.async.caltech.edu (Mika Nystrom) Date: Fri, 01 Jan 2010 15:02:23 -0800 Subject: [M3devel] scope/resolution of foo in interface foo = foo(bar) In-Reply-To: References: <20091230144007.081152474001@birch.elegosoft.com>, <21B2F22D-C1E9-46F2-8434-4CD78DCD7E96@cs.purdue.edu> Message-ID: <20100101230223.355441A2080@async.async.caltech.edu> Jay K writes: ... > >import foo=3B >import foo(bar)=3B >import foo(bar) as foobar=3B >import foo(bar).T as fooT=3B Modula-3 doesn't work like that. You have to say INTERFACE X = G(Y) ... IMPORT X You can't import "G(Y)" directly. Saves having to worry too much about name mangling. Having a generic interface and a normal one with the same name is a common pattern for me, at least. You often have a single supertype and then many subtypes that are related to that supertype by being extended with, say, a field of an arbitrary type. Then you get... INTERFACE Stuff; TYPE T ... END Stuff. GENERIC INTERFACE Stuff(Specializing); IMPORT Stuff; TYPE T = Stuff.T OBJECT special : Specializing.T END; END Stuff. INTERFACE SpecialStuff = Stuff(Special) Very convenient to use the same name at the top level, I think. Mika > > >I doubt all but the first of these are legal=2C but I also don't think they= > are very far fetched >in terms of being reasonable constructs and not difficult to implement. > > >And I'm not sure the presence of the '(' is enough disambiguation for a qui= >ck human reader >or a pleasantly simply enough implementation=2C but maybe. > > >All that is to say=2C I don't think disallowing interface foo =3D foo(bar) = >is so bad. > > > - Jay > >From: hosking at cs.purdue.edu >Date: Fri=2C 1 Jan 2010 14:43:36 -0500 >To: jkrell at elego.de >CC: m3commit at elegosoft.com >Subject: Re: [M3commit] CVS Update: cm3 > > > >That's a bug in m3tk scope management. Probably needs a ticket in the bugs= > database... > > >On 30 Dec 2009=2C at 15:40=2C Jay Krell wrote:CVSROOT: /usr/cvs >Changes by: jkrell at birch. 09/12/30 15:40:06 > >Modified files: > cm3/m3-libs/m3core/src/word/: Long.i3 Long.m3 Word.i3 Word.m3=20 > m3makefile=20 >Added files: > cm3/m3-libs/m3core/src/word/: GenWord.ig GenWord.mg=20 >Removed files: > cm3/m3-libs/m3core/src/word/: Word.ig Word.mg=20 > >Log message: > go back to GenWord > the other front end (Olivetti m3-tk) > doesn't understand > INTERFACE Word =3D Word(WordRep) END Word. > but it does't understand > INTERFACE Word =3D GenWord(WordRep) END Word. > > = > >--_3ac6c68d-ca6e-4c55-9f4d-89e33c42a8f7_ >Content-Type: text/html; charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable > > > > > > >I can understand that the name on the left isn't in scope "yet" on the righ= >t=2C
but what is the algorithm for anyone else using IMPORT?


= >import foo=3B
import foo(bar)=3B
import foo(bar) as foobar=3B
impo= >rt foo(bar).T as fooT=3B


I doubt all but the first of these are = >legal=2C but I also don't think they are very far fetched
in terms of be= >ing reasonable constructs and not difficult to implement.


And I'= >m not sure the presence of the '(' is enough disambiguation for a quick hum= >an reader
or a pleasantly simply enough implementation=2C but maybe.
= >

All that is to say=2C I don't think disallowing interface foo =3D f= >oo(bar) is so bad.


 =3B- Jay


= >From: hosking at cs.purdue.edu
Date: Fri=2C 1 Jan 2010 14:43:36 -0500
To= >: jkrell at elego.de
CC: m3commit at elegosoft.com
Subject: Re: [M3commit] = >CVS Update: cm3

> >
=3B color: rgb(0=2C 0=2C 0)=3B font-family: Helvetica=3B font-size: 12px=3B= > font-style: normal=3B font-variant: normal=3B font-weight: normal=3B lette= >r-spacing: normal=3B line-height: normal=3B text-indent: 0px=3B text-transf= >orm: none=3B white-space: normal=3B word-spacing: 0px=3B">xApple-style-span" style=3D"border-collapse: separate=3B color: rgb(0=2C 0= >=2C 0)=3B font-family: Helvetica=3B font-size: 12px=3B font-style: normal= >=3B font-variant: normal=3B font-weight: normal=3B letter-spacing: normal= >=3B line-height: normal=3B text-indent: 0px=3B text-transform: none=3B whit= >e-space: normal=3B word-spacing: 0px=3B">
d=3B">e=3B color: rgb(0=2C 0=2C 0)=3B font-family: Helvetica=3B font-size: 12px= >=3B font-style: normal=3B font-variant: normal=3B font-weight: normal=3B le= >tter-spacing: normal=3B line-height: normal=3B text-indent: 0px=3B text-tra= >nsform: none=3B white-space: normal=3B word-spacing: 0px=3B">"ecxApple-style-span" style=3D"border-collapse: separate=3B color: rgb(0=2C= > 0=2C 0)=3B font-family: Helvetica=3B font-size: 12px=3B font-style: normal= >=3B font-variant: normal=3B font-weight: normal=3B letter-spacing: normal= >=3B line-height: normal=3B text-indent: 0px=3B text-transform: none=3B whit= >e-space: normal=3B word-spacing: 0px=3B">" style=3D"border-collapse: separate=3B color: rgb(0=2C 0=2C 0)=3B font-fam= >ily: Helvetica=3B font-size: 12px=3B font-style: normal=3B font-variant: no= >rmal=3B font-weight: normal=3B letter-spacing: normal=3B line-height: norma= >l=3B text-indent: 0px=3B text-transform: none=3B white-space: normal=3B wor= >d-spacing: 0px=3B">apse: separate=3B color: rgb(0=2C 0=2C 0)=3B font-family: Helvetica=3B font= >-size: 12px=3B font-style: normal=3B font-variant: normal=3B font-weight: n= >ormal=3B letter-spacing: normal=3B line-height: normal=3B text-indent: 0px= >=3B text-transform: none=3B white-space: normal=3B word-spacing: 0px=3B">pan class=3D"ecxApple-style-span" style=3D"border-collapse: separate=3B col= >or: rgb(0=2C 0=2C 0)=3B font-family: Helvetica=3B font-size: 12px=3B font-s= >tyle: normal=3B font-variant: normal=3B font-weight: normal=3B letter-spaci= >ng: normal=3B line-height: normal=3B text-indent: 0px=3B text-transform: no= >ne=3B white-space: normal=3B word-spacing: 0px=3B">style-span" style=3D"border-collapse: separate=3B color: rgb(0=2C 0=2C 0)= >=3B font-family: Helvetica=3B font-size: 12px=3B font-style: normal=3B font= >-variant: normal=3B font-weight: normal=3B letter-spacing: normal=3B line-h= >eight: normal=3B text-indent: 0px=3B text-transform: none=3B white-space: n= >ormal=3B word-spacing: 0px=3B">"border-collapse: separate=3B color: rgb(0=2C 0=2C 0)=3B font-family: Helve= >tica=3B font-size: 12px=3B font-style: normal=3B font-variant: normal=3B fo= >nt-weight: normal=3B letter-spacing: normal=3B line-height: normal=3B text-= >indent: 0px=3B text-transform: none=3B white-space: normal=3B word-spacing:= > 0px=3B">rate=3B color: rgb(0=2C 0=2C 0)=3B font-family: Helvetica=3B font-size: 12p= >x=3B font-style: normal=3B font-variant: normal=3B font-weight: normal=3B l= >etter-spacing: normal=3B line-height: normal=3B text-indent: 0px=3B text-tr= >ansform: none=3B white-space: normal=3B word-spacing: 0px=3B">
ass=3D"ecxApple-style-span" style=3D"font-size: medium=3B">cxApple-style-span" color=3D"#0000ff" face=3D"'Gill Sans'">That's a bug in = >m3tk scope management.  =3BProbably needs a ticket in the bugs database= >...
pan>
>
>
On 30 Dec 2009=2C at 15:40=2C Jay Krell wrote:

=3D"ecxApple-interchange-newline">
CVSROOT:cxApple-tab-span" style=3D"white-space: pre=3B"> /usr/cvs
Changes= > by: >jkrell at birch.=3B"> 09/12/30 15:40:06

Modified files:
Apple-tab-span" style=3D"white-space: pre=3B"> cm3/m3-libs/m3core/sr= >c/word/: Long.i3 Long.m3 Word.i3 Word.m3
an" style=3D"white-space: pre=3B">  =3B =3B =3B =3B= > =3B =3B =3B =3B =3B =3B =3B =3B =3B&nb= >sp=3B =3B =3B =3B =3B =3B =3B =3B =3B = >=3B =3B =3B =3B =3B =3B =3Bm3makefile
Added fil= >es:
pan>cm3/m3-libs/m3core/src/word/: GenWord.ig GenWord.mg
Removed files:<= >br> = >cm3/m3-libs/m3core/src/word/: Word.ig Word.mg

Log message:
class=3D"ecxApple-tab-span" style=3D"white-space: pre=3B">
go back = >to GenWord
=3B"> the other front end (Olivetti m3-tk)
e-tab-span" style=3D"white-space: pre=3B"> doesn't understand
an class=3D"ecxApple-tab-span" style=3D"white-space: pre=3B">
INTERF= >ACE Word =3D Word(WordRep) END Word.
tyle=3D"white-space: pre=3B"> but it does't understand
s=3D"ecxApple-tab-span" style=3D"white-space: pre=3B"> INTERFACE Wor= >d =3D GenWord(WordRep) END Word.

= > >= > >--_3ac6c68d-ca6e-4c55-9f4d-89e33c42a8f7_-- From jay.krell at cornell.edu Sat Jan 2 00:05:44 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 1 Jan 2010 23:05:44 +0000 Subject: [M3devel] C generating back end Message-ID: Fyi I finally looked at the 2.x implementation and the outputing of C was implemented fairly directly at the m3front layer. There wasn't the "M3CG" stuff. Thus, the "easiest" way to get back such functionality would probably be to "interleave" the old code and the new code within m3front. The "cleaner" way is probably to implement a new M3CG though and leave m3front unchanged. I still think generating portable C a great way to achieve portability. Better yet maybe, generate C++ and use its exception handling feature. (ok, maybe generate both, in case some systems lack C++ support) I realize there are several ways to view this though. gcc backend provides enough portability imagine IA64_NT though. or Plan9. or even OpenBSD or Darwin where there are long standing forks (The OpenBSD patches are small and we carry/apply them. The Apple changes I think are mainly in the frontends which I think is how we get by.) For efficient exception handling we should be able to use libunwind on most targets. llvm would provide good portability and maybe other benefits like perf less reach than gcc but hits the major platforms difficult for me to get started with sorry integrated backend could/should be ported around and is fast a lot of work I think the first steps here are to learn about mach-o and elf file formats as part of ports for other x86 targets. I've started a macho-dumper. burg or others - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 2 00:42:34 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 1 Jan 2010 18:42:34 -0500 Subject: [M3devel] C generating back end In-Reply-To: References: Message-ID: <0B27C390-09BA-4B09-9EE2-72602331FB94@cs.purdue.edu> On 1 Jan 2010, at 18:05, Jay K wrote: > Fyi I finally looked at the 2.x implementation and the outputing of > C was implemented fairly directly at the m3front layer. > There wasn't the "M3CG" stuff. > > > Thus, the "easiest" way to get back such functionality would > probably be to "interleave" the old code and the new code within m3front. I'd like to avoid that sort of interleaving. > The "cleaner" way is probably to implement a new M3CG though and > leave m3front unchanged. This is a much better plan. > I still think generating portable C a great way to achieve portability. > Better yet maybe, generate C++ and use its exception handling feature. > (ok, maybe generate both, in case some systems lack C++ support) We can use the gcc-backend exception handling support if anyone was prepared to work on it. > realize there are several ways to view this though. > > gcc backend provides enough portability > imagine IA64_NT though. or Plan9. or even OpenBSD > or Darwin where there are long standing forks > (The OpenBSD patches are small and we carry/apply them. > The Apple changes I think are mainly in the frontends > which I think is how we get by.) > > For efficient exception handling we should be able to use libunwind on most targets. > > llvm would provide good portability and maybe other benefits like perf > less reach than gcc but hits the major platforms > difficult for me to get started with sorry > > integrated backend could/should be ported around and is fast > a lot of work > I think the first steps here are to learn about mach-o and elf file formats > as part of ports for other x86 targets. I've started a macho-dumper. > > burg or others > > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Sat Jan 2 02:27:55 2010 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sat, 2 Jan 2010 01:27:55 +0000 (GMT) Subject: [M3devel] C generating back end In-Reply-To: <0B27C390-09BA-4B09-9EE2-72602331FB94@cs.purdue.edu> Message-ID: <694151.75147.qm@web23608.mail.ird.yahoo.com> Hi all: Olivetti had the the original development environment written with a C generating backend written in C for different operating system machines, they intended to realease it fully (probably it was) but performance showed was inferior to that of SRC environment at the time 2.x (Modula-3 to C written in Modula-3), which led to include Olivetti front end part as a library front end being part of the SRC distribution, later to deploy Network Objects high level intermediate code network logical layer. Having a C backend this days wouldn't make sense if it was actually developed at some point, and up to a Professor remembers RMS wanted this to be donated to FSF so it could led to some sort to GPLed system, but there wasn't such a donation or haven't been done yet and it probably was related to the performance comparison (in the time of Olivetti and SRC 2.x systems) reason mentioned by Mick Jordan (see http://compilers.iecc.com/comparch/article/90-08-046 ) and later to M3CG (due SRC Modula-2+ system low level intermediate code) interface which has proven to be a good compromise between portability and performance. If we could prove that Olivetti backend could be a plus in terms of M3 performance and portability to get it back and compare its actual performance with nowadays M3CG backend performance then this would have a point Hope it helps, thanks in advance --- El vie, 1/1/10, Tony Hosking escribi?: > De: Tony Hosking > Asunto: Re: [M3devel] C generating back end > Para: "Jay K" > CC: "m3devel" > Fecha: viernes, 1 de enero, 2010 18:42 > On 1 Jan > 2010, at 18:05, Jay K > wrote: > Fyi I finally > looked at the 2.x implementation and the outputing of > C was implemented fairly directly at the m3front layer. > There wasn't the "M3CG" stuff. > > > Thus, the "easiest" way to get back such > functionality would > probably be to "interleave" the old code and the > new code within m3front. > > I'd like to avoid that sort of > interleaving. > The > "cleaner" way is probably to implement a new M3CG > though and > leave m3front unchanged. > > This is a much better plan. > I still think > generating portable C a great way to achieve portability. > Better yet maybe, generate C++ and use its exception > handling feature. > (ok, maybe generate both, in case some systems lack C++ > support) > > We can use the gcc-backend exception handling > support if anyone was prepared to work on it. > realize > there are several ways to view this though. > > gcc backend provides enough portability > imagine IA64_NT though. or Plan9. > or even OpenBSD > or Darwin where there are > long standing forks > (The OpenBSD patches are > small and we carry/apply them. > The Apple changes I think > are mainly in the frontends > which I think is how we get > by.) > > For efficient exception handling > we should be able to use libunwind on most targets. > > llvm would provide good portability and maybe other > benefits like perf > less reach than gcc but hits the > major platforms > difficult for me to get started > with sorry > > integrated backend could/should be ported around and > is fast > a lot of work > I think the first steps here are > to learn about mach-o and elf file formats > as part of ports for > other x86 targets. I've started a macho-dumper. > > burg or others > > - Jay > > > From wagner at elegosoft.com Sat Jan 2 11:54:06 2010 From: wagner at elegosoft.com (Olaf Wagner) Date: Sat, 02 Jan 2010 11:54:06 +0100 Subject: [M3devel] Fwd: [CM3] #1080: CVSUPD server hangs if used with -C option In-Reply-To: <726BCE28-8561-40BF-BFBD-F96EC4151B50@cs.purdue.edu> References: <20091229184748.frhga784gkk4cosg@mail.elegosoft.com> <726BCE28-8561-40BF-BFBD-F96EC4151B50@cs.purdue.edu> Message-ID: <20100102115406.ck9y12tv4okcoso8@mail.elegosoft.com> Quoting Tony Hosking : > What does -C do? Make it a server process. From the manual: -C maxClients Limits the number of simultaneous clients to maxClients. Clients beyond the specified maximum are politely refused service. If this option is not specified, cvsupd serves one client in the foreground and then exits. Olaf > On 29 Dec 2009, at 12:47, Olaf Wagner wrote: > >> Any ideas? Interaction problem between threads and select? >> >> Olaf >> >> ----- Forwarded message from bugs at elego.de ----- >> Date: Tue, 29 Dec 2009 16:23:23 -0000 >> From: CM3 >> Reply-To: CM3 >> Subject: [CM3] #1080: CVSUPD server hangs if used with -C option >> To: @MISSING_DOMAIN >> >> #1080: CVSUPD server hangs if used with -C option >> -----------------------------+---------------------------------------------- >> Reporter: rajeshvadivelu | Owner: wagner >> Type: sw-bug | Status: new >> Priority: high | Milestone: >> Component: sys | Version: 5.8-RC3 >> Severity: critical | Keywords: >> Relnote: | Confidential: no >> Org: Collabnet | Estimatedhours: 0 >> Hours: 0 | Billable: 0 >> Totalhours: 0 | >> -----------------------------+---------------------------------------------- >> Htr: >> Install cvsup from cm3-bin-ws-cvsup-LINUXLIBC6-5.8.4-RC4.tgz package. >> >> Start the cvsupd server with -C option >> >> ./cvsupd -b /data/cvsupd -C 2 >> >> Try cvsup client to connect to the sever >> >> ./cvsup -g -L 2 /tmp/cvsupd.cfg >> >> The client connection will hang and after sometime we will get >> "Inactivity timeout" >> >> >> Fix: >> >> >> >> Env: >> >> >> -----------------------------+---------------------------------------------- >> In a RHEL5 32bit box I was trying to run cvsupd server to mirror my cvs >> repo. I did used cm3-bin-ws-cvsup-LINUXLIBC6-5.8.4-RC4.tgz to get the >> cvsup installed. >> >> The server starts find and there was no issues if I start the server >> without -C option. >> >> Starting cvsupd server without -C option >> >> $ ./cvsupd -b /u2/site/data/cvsupd >> 2009.12.29 21:31:05 IST [6225]: CVSup server started >> 2009.12.29 21:31:05 IST [6225]: Software version: 2009-08-30 21:02:46 >> 2009.12.29 21:31:05 IST [6225]: Protocol version: 17.0 >> 2009.12.29 21:31:05 IST [6225]: Ready to service requests >> >> Then I did a client request as below >> >> $ ./cvsup -g -L 2 /tmp/cvsupd.cfg >> Parsing supfile "/tmp/cvsupd.cfg" >> Connecting to myserver.com >> Connected to myserver.com >> Rejected by server: Access denied >> Will retry at 21:37:09 >> >> So the request was successful and I get a valid error message at the >> client. >> >> But when I start the server with -C option like the one as below, requests >> from client are hanging and eventually getting "Inactivity timeout" after >> sometime. >> >> $ ./cvsupd -b /u2/site/data/cvsupd -C 2 >> >> When ever a new client connection was made, this daemon clones another >> cvsupd process and it also hangs. So none of the client request were >> processed. >> >> Strace of the main cvsupd server process, when a new client request was >> fired. >> >> ----------------------------------- >> select(4, [3], [], [3], {0, 39000}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 1 (in [3], left {0, 553000}) >> accept(3, {sa_family=AF_INET, sin_port=htons(51221), >> sin_addr=inet_addr("208.75.198.60")}, [16]) = 6 >> setsockopt(6, SOL_SOCKET, SO_LINGER, {onoff=1, linger=1}, 8) = 0 >> setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0 >> fcntl64(6, F_GETFL) = 0x2 (flags O_RDWR) >> fcntl64(6, F_SETFL, O_RDWR|O_NONBLOCK) = 0 >> gettimeofday({1262103026, 146476}, NULL) = 0 >> open("/u2/site/data/cvsupd/cvsupd.access", O_RDONLY|O_LARGEFILE) = 7 >> fstat64(7, {st_mode=S_IFREG|0755, st_size=215, ...}) = 0 >> _llseek(7, 0, [0], SEEK_CUR) = 0 >> fstat64(7, {st_mode=S_IFREG|0755, st_size=215, ...}) = 0 >> close(7) = 0 >> gettimeofday({1262103026, 147481}, NULL) = 0 >> stat64("/u2/site/data/cvsupd/cvsupd.class", 0xbf809c04) = -1 ENOENT (No >> such file or directory) >> write(5, "\0", 1) = 1 >> futex(0x91580f0, FUTEX_WAKE, 1) = 1 >> futex(0x9158098, FUTEX_WAKE, 1) = 1 >> futex(0x91580b8, FUTEX_WAKE, 1) = 1 >> futex(0x91580bc, FUTEX_WAIT, 5, NULL) = -1 EAGAIN (Resource temporarily >> unavailable) >> futex(0x9158098, FUTEX_WAKE, 1) = 0 >> clone(child_stack=0, >> flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, >> child_tidptr=0xb7f43708) = 6543 >> futex(0x915a484, 0x5 /* FUTEX_??? */, 1) = 1 >> futex(0x915a460, FUTEX_WAKE, 1) = 1 >> futex(0x91580f0, FUTEX_WAKE, 1) = 1 >> futex(0x9158098, FUTEX_WAKE, 1) = 1 >> futex(0x91580b8, FUTEX_WAKE, 1) = 1 >> futex(0x91580bc, FUTEX_WAIT, 7, NULL) = -1 EAGAIN (Resource temporarily >> unavailable) >> futex(0x9158098, FUTEX_WAKE, 1) = 0 >> close(6) = 0 >> accept(3, 0xbf809e44, [16]) = -1 EAGAIN (Resource temporarily >> unavailable) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >> >> ------------------------------------ >> >> gdb backtrace of the main cvsupd server process >> >> ------------------------------------ >> >> #0 0x00a2a402 in __kernel_vsyscall () >> #1 0x0026efb1 in ___newselect_nocancel () from /lib/libc.so.6 >> #2 0x00f8965b in Unix__select (nfds=4, readfds=0xb7f9df78, >> writefds=0xb7f9df88, exceptfds=0xb7f9df98, timeout=0xbfed9410) at >> ../src/unix/Common/UnixC.c:301 >> #3 0x00f85f4b in ThreadPThread__XIOWait__CallSelect.779 (M3_Cwb5VA_nfd=4, >> M3_A4bqCj_timeout=0xbfed9410) at >> ../src/thread/PTHREAD/ThreadPThread.m3:900 >> #4 0x00f85c7a in ThreadPThread__XIOWait (M3_BXP32l_self=0xb7f9400c, >> M3_Cwb5VA_fd=3, M3_AicXUJ_read=1 '\001', >> M3_CtKayy_interval=1.7976931348623157e+308, M3_AicXUJ_alertable=1 '\001') >> at ../src/thread/PTHREAD/ThreadPThread.m3:936 >> #5 0x00f8589d in SchedulerPosix__IOAlertWait (M3_Cwb5VA_fd=3, >> M3_AicXUJ_read=1 '\001', M3_CtKayy_timeoutInterval=-1) at >> ../src/thread/PTHREAD/ThreadPThread.m3:854 >> #6 0x00e4b499 in TCPMisc__AcceptFrom (M3_AahksS_c=0xb7f9ca48, >> M3_DoBjMZ_peer=0xbfed9970) at ../src/POSIX/TCP.m3:458 >> #7 0x0807bcbf in FSServer__Run (M3_DS26rk_self=0xb7f9c9fc) at >> ../src/FSServer.m3:153 >> #8 0x080934fd in Main_M3 (M3_AcxOUs_mode=1) at ../src/Main.m3:336 >> #9 0x00f717c8 in RTLinker__RunMainBody (M3_DjPxE3_m=0x80a11a0) at >> ../src/runtime/common/RTLinker.m3:399 >> #10 0x00f70b82 in RTLinker__AddUnitI (M3_DjPxE3_m=0x80a11a0) at >> ../src/runtime/common/RTLinker.m3:113 >> #11 0x00f70c10 in RTLinker__AddUnit (M3_DjPxE5_b=0x8090f4e) at >> ../src/runtime/common/RTLinker.m3:122 >> #12 0x0804db1e in main (argc=5, argv=0xbfeda124, envp=0xbfeda13c) at >> _m3main.mc:4 >> ------------------------------------------------ >> >> >> strace of the cloned cvsupd process >> >> ----------------------------------- >> >> futex(0x91580bc, FUTEX_WAIT, 3, NULL >> >> ----------------------------------- >> >> gdb backtrace of the cloned cvsupd process >> >> ----------------------------------- >> >> #0 0x00a2a402 in __kernel_vsyscall () >> #1 0x00320146 in pthread_cond_wait@@GLIBC_2.3.2 () from >> /lib/libpthread.so.0 >> #2 0x00f886e6 in ThreadPThread__pthread_cond_wait (cond=0x89c60b8, >> mutex=0x89c6098) at ../src/thread/PTHREAD/ThreadPThreadC.c:326 >> #3 0x00f81d9d in ThreadPThread__XWait (M3_BXP32l_self=0xb7f9400c, >> M3_AYIbX3_m=0xb7f9c8d8, M3_Bl0jv4_c=0xb7f9c8f4, M3_AicXUJ_alertable=0 >> '\0') at ../src/thread/PTHREAD/ThreadPThread.m3:238 >> #4 0x00f821ae in Thread__Wait (M3_AYIbX3_m=0xb7f9c8d8, >> M3_Bl0jv4_c=0xb7f9c8f4) at ../src/thread/PTHREAD/ThreadPThread.m3:280 >> #5 0x00bd4e14 in SigHandler__ChangeState (M3_BnMAgS_d=0xb7f9c4bc, >> M3_AkN0P6_state=2 '\002') at ../src/SigHandler.m3:105 >> #6 0x00bd5ba6 in SigHandler__ShutDown () at ../src/SigHandler.m3:243 >> #7 0x0807cbac in FSServer_M3_LINE_230.718 (L_2=0xbfed95d0) at >> ../src/FSServer.m3:231 >> #8 0x0807c956 in FSServer__Run (M3_DS26rk_self=0xb7f9c9fc) at >> ../src/FSServer.m3:227 >> #9 0x080934fd in Main_M3 (M3_AcxOUs_mode=1) at ../src/Main.m3:336 >> #10 0x00f717c8 in RTLinker__RunMainBody (M3_DjPxE3_m=0x80a11a0) at >> ../src/runtime/common/RTLinker.m3:399 >> #11 0x00f70b82 in RTLinker__AddUnitI (M3_DjPxE3_m=0x80a11a0) at >> ../src/runtime/common/RTLinker.m3:113 >> #12 0x00f70c10 in RTLinker__AddUnit (M3_DjPxE5_b=0x8090f4e) at >> ../src/runtime/common/RTLinker.m3:122 >> #13 0x0804db1e in main (argc=5, argv=0xbfeda124, envp=0xbfeda13c) at >> _m3main.mc:4 >> >> ------------------------------------------- >> >> So it looks like both the main and cloned cvsupd processes were waiting >> for a response from the kernel call "__kernel_vsyscall ()". Under what >> condition will this happen? Am I doing something wrong here? >> >> -- >> Ticket URL: >> CM3 >> Critical Mass Modula3 Compiler >> >> >> ----- End forwarded message ----- >> >> >> -- >> Olaf Wagner -- elego Software Solutions GmbH >> Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany >> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 >> http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin >> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 >> > > -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From rodney_bates at lcwb.coop Sat Jan 2 18:20:04 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 02 Jan 2010 11:20:04 -0600 Subject: [M3devel] scope/resolution of foo in interface foo = foo(bar) In-Reply-To: <20100101230223.355441A2080@async.async.caltech.edu> References: <20091230144007.081152474001@birch.elegosoft.com>, <21B2F22D-C1E9-46F2-8434-4CD78DCD7E96@cs.purdue.edu> <20100101230223.355441A2080@async.async.caltech.edu> Message-ID: <4B3F8044.2080403@lcwb.coop> Mika Nystrom wrote: > Jay K writes: > ... >> import foo=3B >> import foo(bar)=3B >> import foo(bar) as foobar=3B >> import foo(bar).T as fooT=3B > > Modula-3 doesn't work like that. > > You have to say > > INTERFACE X = G(Y) ... > > IMPORT X > > You can't import "G(Y)" directly. Saves having to worry too much about > name mangling. > > Having a generic interface and a normal one with the same name is a common > pattern for me, at least. > > You often have a single supertype and then many subtypes that are related > to that supertype by being extended with, say, a field of an arbitrary type. > > Then you get... > > INTERFACE Stuff; TYPE T ... END Stuff. > > GENERIC INTERFACE Stuff(Specializing); > IMPORT Stuff; > TYPE T = Stuff.T OBJECT special : Specializing.T END; > END Stuff. > > INTERFACE SpecialStuff = Stuff(Special) > > Very convenient to use the same name at the top level, I think. > > Mika Yuck! I hate this. One of the things I really hate about Java and C++ is having many different ways in which a reference to an identifier is looked up, depending on the context of the reference. This is one of the big ways a language gets obscenely overcomplicated without providing any useful benefits. One of Modula-3's strengths is that when an unqualified identifier is referenced, it is always looked up according to the same rules, no matter what kind of thing it is. Only afterwards are semantic rules applied like, e.g., the context requires a type but the identifier is a constant. Except for this example, which I had missed up until now. IMPORT Stuff (and also EXPORTS Stuff) looks up Stuff as a global name in a different way from INTERFACE SpecialStuff = Stuff(Special). Unfortunately, the language fails to address this at all in 2.5.5, and the implementation managed to get away with violating the principle. So now we have a bit of a slip into the evil world of junk programming languages. As for its being convenient, it may save a bit of effort during the initial coding phase, by not requiring you to think up distinct names, but it is a cruel and inhuman punishment to inflict on the miserable but innocent wretch who has to maintain your code later. And in just case someone needs to be reminded, coding is short. Maintenance is long, sometimes almost forever. We really should amend the language to say that ordinary and generic interfaces combined must all have distinct global names. Likewise for ordinary and generic modules. > From rodney_bates at lcwb.coop Sat Jan 2 18:42:34 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 02 Jan 2010 11:42:34 -0600 Subject: [M3devel] scope/resolution of foo in interface foo = foo(bar) In-Reply-To: <20100101230223.355441A2080@async.async.caltech.edu> References: <20091230144007.081152474001@birch.elegosoft.com>, <21B2F22D-C1E9-46F2-8434-4CD78DCD7E96@cs.purdue.edu> <20100101230223.355441A2080@async.async.caltech.edu> Message-ID: <4B3F858A.8070001@lcwb.coop> Mika Nystrom wrote: > Jay K writes: > ... >> import foo=3B >> import foo(bar)=3B >> import foo(bar) as foobar=3B >> import foo(bar).T as fooT=3B > > Modula-3 doesn't work like that. > > You have to say > > INTERFACE X = G(Y) ... > > IMPORT X > > You can't import "G(Y)" directly. Saves having to worry too much about > name mangling. > On a separate issue, one of the things that the C++ template facility really botched badly is that instantiations not only can be, but must be, anonymous. So every single time you want to refer to it, you have to repeat the template actuals list. It makes for some very ponderous and confusing code to read, especially if there are multiple instantiations involved. It also makes the semantic analysis unnecessarily difficult for both the human reader and compiler. In Modula-3 an instantiation must be done once, giving it a simple name, with the name used thereafter everywhere the instantiation is referred-to. From jay.krell at cornell.edu Sat Jan 2 20:18:58 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 2 Jan 2010 19:18:58 +0000 Subject: [M3devel] scope/resolution of foo in interface foo = foo(bar) In-Reply-To: <4B3F858A.8070001@lcwb.coop> References: <20091230144007.081152474001@birch.elegosoft.com>, , <21B2F22D-C1E9-46F2-8434-4CD78DCD7E96@cs.purdue.edu> , <20100101230223.355441A2080@async.async.caltech.edu>, <4B3F858A.8070001@lcwb.coop> Message-ID: > Date: Sat, 2 Jan 2010 11:42:34 -0600 > From: rodney > On a separate issue, one of the things that the C++ template facility really > botched badly is that instantiations not only can be, but must be, anonymous. Can be, but not must be. for types: typedef vector vi_t. for functions, well, usually the parameters are deduced and you don't have to say them: template T max(const T& a, const T& b) { return (a > b ? a : b); } max(1, 2); If you have something like: template T* New() { return new T(); } then you do have to say New(). You could do something onerous like: Foo* (*const NewFoo)() = New; There is a new feature that might enable: const auto NewFoo = New; but really, deduction of function template parameters is a very good thing, no need to fight it, and making the parameters explicit for some scenarios is not so bad. There are some very confusing things about templates: How much can be checked without instantiation? Which names are bound at template definition vs. instantiation? Can "template metaprogramming" be done in a more direct way instead of seemingly just being an accident? And (with reverse spin) there are some very powerful things you can do with templates: template meta programming :) very good levels of inlining where otherwise you'd have little choice but to use function pointers and have poor efficiency (though, not that you can't implement things easily enough and have them at least work without templates) not sure the term, but have you seen how in C++ you can write: a = b + c + d + e; where the types involves are vectors/matrices and it compiles down to have no temporary vectors/matrices. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 2 20:35:59 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 2 Jan 2010 13:35:59 -0600 Subject: [M3devel] Fwd: [CM3] #1080: CVSUPD server hangs if used with -C option In-Reply-To: <20100102115406.ck9y12tv4okcoso8@mail.elegosoft.com> References: <20091229184748.frhga784gkk4cosg@mail.elegosoft.com> <726BCE28-8561-40BF-BFBD-F96EC4151B50@cs.purdue.edu> <20100102115406.ck9y12tv4okcoso8@mail.elegosoft.com> Message-ID: <8DB9B34C-2F82-4AE7-ADC4-100F01C5F874@cs.purdue.edu> So, what's changed recently to break this? It must have been working relatively recently. Sent from my iPhone On Jan 2, 2010, at 4:54 AM, Olaf Wagner wrote: > Quoting Tony Hosking : > >> What does -C do? > > Make it a server process. From the manual: > > -C maxClients > Limits the number of simultaneous clients to > maxClients. > Clients beyond the specified maximum are politely > refused > service. > > If this option is not specified, cvsupd serves one > client in > the foreground and then exits. > > Olaf > >> On 29 Dec 2009, at 12:47, Olaf Wagner wrote: >> >>> Any ideas? Interaction problem between threads and select? >>> >>> Olaf >>> >>> ----- Forwarded message from bugs at elego.de ----- >>> Date: Tue, 29 Dec 2009 16:23:23 -0000 >>> From: CM3 >>> Reply-To: CM3 >>> Subject: [CM3] #1080: CVSUPD server hangs if used with -C option >>> To: @MISSING_DOMAIN >>> >>> #1080: CVSUPD server hangs if used with -C option >>> ----------------------------- >>> +---------------------------------------------- >>> Reporter: rajeshvadivelu | Owner: wagner >>> Type: sw-bug | Status: new >>> Priority: high | Milestone: >>> Component: sys | Version: 5.8-RC3 >>> Severity: critical | Keywords: >>> Relnote: | Confidential: no >>> Org: Collabnet | Estimatedhours: 0 >>> Hours: 0 | Billable: 0 >>> Totalhours: 0 | >>> ----------------------------- >>> +---------------------------------------------- >>> Htr: >>> Install cvsup from cm3-bin-ws-cvsup-LINUXLIBC6-5.8.4-RC4.tgz >>> package. >>> >>> Start the cvsupd server with -C option >>> >>> ./cvsupd -b /data/cvsupd -C 2 >>> >>> Try cvsup client to connect to the sever >>> >>> ./cvsup -g -L 2 /tmp/cvsupd.cfg >>> >>> The client connection will hang and after sometime we will get >>> "Inactivity timeout" >>> >>> >>> Fix: >>> >>> >>> >>> Env: >>> >>> >>> ----------------------------- >>> +---------------------------------------------- >>> In a RHEL5 32bit box I was trying to run cvsupd server to mirror >>> my cvs >>> repo. I did used cm3-bin-ws-cvsup-LINUXLIBC6-5.8.4-RC4.tgz to get >>> the >>> cvsup installed. >>> >>> The server starts find and there was no issues if I start the server >>> without -C option. >>> >>> Starting cvsupd server without -C option >>> >>> $ ./cvsupd -b /u2/site/data/cvsupd >>> 2009.12.29 21:31:05 IST [6225]: CVSup server started >>> 2009.12.29 21:31:05 IST [6225]: Software version: 2009-08-30 >>> 21:02:46 >>> 2009.12.29 21:31:05 IST [6225]: Protocol version: 17.0 >>> 2009.12.29 21:31:05 IST [6225]: Ready to service requests >>> >>> Then I did a client request as below >>> >>> $ ./cvsup -g -L 2 /tmp/cvsupd.cfg >>> Parsing supfile "/tmp/cvsupd.cfg" >>> Connecting to myserver.com >>> Connected to myserver.com >>> Rejected by server: Access denied >>> Will retry at 21:37:09 >>> >>> So the request was successful and I get a valid error message at the >>> client. >>> >>> But when I start the server with -C option like the one as below, >>> requests >>> from client are hanging and eventually getting "Inactivity >>> timeout" after >>> sometime. >>> >>> $ ./cvsupd -b /u2/site/data/cvsupd -C 2 >>> >>> When ever a new client connection was made, this daemon clones >>> another >>> cvsupd process and it also hangs. So none of the client request were >>> processed. >>> >>> Strace of the main cvsupd server process, when a new client >>> request was >>> fired. >>> >>> ----------------------------------- >>> select(4, [3], [], [3], {0, 39000}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 1 (in [3], left {0, >>> 553000}) >>> accept(3, {sa_family=AF_INET, sin_port=htons(51221), >>> sin_addr=inet_addr("208.75.198.60")}, [16]) = 6 >>> setsockopt(6, SOL_SOCKET, SO_LINGER, {onoff=1, linger=1}, 8) = 0 >>> setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0 >>> fcntl64(6, F_GETFL) = 0x2 (flags O_RDWR) >>> fcntl64(6, F_SETFL, O_RDWR|O_NONBLOCK) = 0 >>> gettimeofday({1262103026, 146476}, NULL) = 0 >>> open("/u2/site/data/cvsupd/cvsupd.access", O_RDONLY|O_LARGEFILE) = 7 >>> fstat64(7, {st_mode=S_IFREG|0755, st_size=215, ...}) = 0 >>> _llseek(7, 0, [0], SEEK_CUR) = 0 >>> fstat64(7, {st_mode=S_IFREG|0755, st_size=215, ...}) = 0 >>> close(7) = 0 >>> gettimeofday({1262103026, 147481}, NULL) = 0 >>> stat64("/u2/site/data/cvsupd/cvsupd.class", 0xbf809c04) = -1 >>> ENOENT (No >>> such file or directory) >>> write(5, "\0", 1) = 1 >>> futex(0x91580f0, FUTEX_WAKE, 1) = 1 >>> futex(0x9158098, FUTEX_WAKE, 1) = 1 >>> futex(0x91580b8, FUTEX_WAKE, 1) = 1 >>> futex(0x91580bc, FUTEX_WAIT, 5, NULL) = -1 EAGAIN (Resource >>> temporarily >>> unavailable) >>> futex(0x9158098, FUTEX_WAKE, 1) = 0 >>> clone(child_stack=0, >>> flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, >>> child_tidptr=0xb7f43708) = 6543 >>> futex(0x915a484, 0x5 /* FUTEX_??? */, 1) = 1 >>> futex(0x915a460, FUTEX_WAKE, 1) = 1 >>> futex(0x91580f0, FUTEX_WAKE, 1) = 1 >>> futex(0x9158098, FUTEX_WAKE, 1) = 1 >>> futex(0x91580b8, FUTEX_WAKE, 1) = 1 >>> futex(0x91580bc, FUTEX_WAIT, 7, NULL) = -1 EAGAIN (Resource >>> temporarily >>> unavailable) >>> futex(0x9158098, FUTEX_WAKE, 1) = 0 >>> close(6) = 0 >>> accept(3, 0xbf809e44, [16]) = -1 EAGAIN (Resource >>> temporarily >>> unavailable) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) >>> >>> ------------------------------------ >>> >>> gdb backtrace of the main cvsupd server process >>> >>> ------------------------------------ >>> >>> #0 0x00a2a402 in __kernel_vsyscall () >>> #1 0x0026efb1 in ___newselect_nocancel () from /lib/libc.so.6 >>> #2 0x00f8965b in Unix__select (nfds=4, readfds=0xb7f9df78, >>> writefds=0xb7f9df88, exceptfds=0xb7f9df98, timeout=0xbfed9410) at >>> ../src/unix/Common/UnixC.c:301 >>> #3 0x00f85f4b in ThreadPThread__XIOWait__CallSelect.779 >>> (M3_Cwb5VA_nfd=4, >>> M3_A4bqCj_timeout=0xbfed9410) at >>> ../src/thread/PTHREAD/ThreadPThread.m3:900 >>> #4 0x00f85c7a in ThreadPThread__XIOWait (M3_BXP32l_self=0xb7f9400c, >>> M3_Cwb5VA_fd=3, M3_AicXUJ_read=1 '\001', >>> M3_CtKayy_interval=1.7976931348623157e+308, M3_AicXUJ_alertable=1 >>> '\001') >>> at ../src/thread/PTHREAD/ThreadPThread.m3:936 >>> #5 0x00f8589d in SchedulerPosix__IOAlertWait (M3_Cwb5VA_fd=3, >>> M3_AicXUJ_read=1 '\001', M3_CtKayy_timeoutInterval=-1) at >>> ../src/thread/PTHREAD/ThreadPThread.m3:854 >>> #6 0x00e4b499 in TCPMisc__AcceptFrom (M3_AahksS_c=0xb7f9ca48, >>> M3_DoBjMZ_peer=0xbfed9970) at ../src/POSIX/TCP.m3:458 >>> #7 0x0807bcbf in FSServer__Run (M3_DS26rk_self=0xb7f9c9fc) at >>> ../src/FSServer.m3:153 >>> #8 0x080934fd in Main_M3 (M3_AcxOUs_mode=1) at ../src/Main.m3:336 >>> #9 0x00f717c8 in RTLinker__RunMainBody (M3_DjPxE3_m=0x80a11a0) at >>> ../src/runtime/common/RTLinker.m3:399 >>> #10 0x00f70b82 in RTLinker__AddUnitI (M3_DjPxE3_m=0x80a11a0) at >>> ../src/runtime/common/RTLinker.m3:113 >>> #11 0x00f70c10 in RTLinker__AddUnit (M3_DjPxE5_b=0x8090f4e) at >>> ../src/runtime/common/RTLinker.m3:122 >>> #12 0x0804db1e in main (argc=5, argv=0xbfeda124, envp=0xbfeda13c) at >>> _m3main.mc:4 >>> ------------------------------------------------ >>> >>> >>> strace of the cloned cvsupd process >>> >>> ----------------------------------- >>> >>> futex(0x91580bc, FUTEX_WAIT, 3, NULL >>> >>> ----------------------------------- >>> >>> gdb backtrace of the cloned cvsupd process >>> >>> ----------------------------------- >>> >>> #0 0x00a2a402 in __kernel_vsyscall () >>> #1 0x00320146 in pthread_cond_wait@@GLIBC_2.3.2 () from >>> /lib/libpthread.so.0 >>> #2 0x00f886e6 in ThreadPThread__pthread_cond_wait (cond=0x89c60b8, >>> mutex=0x89c6098) at ../src/thread/PTHREAD/ThreadPThreadC.c:326 >>> #3 0x00f81d9d in ThreadPThread__XWait (M3_BXP32l_self=0xb7f9400c, >>> M3_AYIbX3_m=0xb7f9c8d8, M3_Bl0jv4_c=0xb7f9c8f4, >>> M3_AicXUJ_alertable=0 >>> '\0') at ../src/thread/PTHREAD/ThreadPThread.m3:238 >>> #4 0x00f821ae in Thread__Wait (M3_AYIbX3_m=0xb7f9c8d8, >>> M3_Bl0jv4_c=0xb7f9c8f4) at ../src/thread/PTHREAD/ >>> ThreadPThread.m3:280 >>> #5 0x00bd4e14 in SigHandler__ChangeState (M3_BnMAgS_d=0xb7f9c4bc, >>> M3_AkN0P6_state=2 '\002') at ../src/SigHandler.m3:105 >>> #6 0x00bd5ba6 in SigHandler__ShutDown () at ../src/ >>> SigHandler.m3:243 >>> #7 0x0807cbac in FSServer_M3_LINE_230.718 (L_2=0xbfed95d0) at >>> ../src/FSServer.m3:231 >>> #8 0x0807c956 in FSServer__Run (M3_DS26rk_self=0xb7f9c9fc) at >>> ../src/FSServer.m3:227 >>> #9 0x080934fd in Main_M3 (M3_AcxOUs_mode=1) at ../src/Main.m3:336 >>> #10 0x00f717c8 in RTLinker__RunMainBody (M3_DjPxE3_m=0x80a11a0) at >>> ../src/runtime/common/RTLinker.m3:399 >>> #11 0x00f70b82 in RTLinker__AddUnitI (M3_DjPxE3_m=0x80a11a0) at >>> ../src/runtime/common/RTLinker.m3:113 >>> #12 0x00f70c10 in RTLinker__AddUnit (M3_DjPxE5_b=0x8090f4e) at >>> ../src/runtime/common/RTLinker.m3:122 >>> #13 0x0804db1e in main (argc=5, argv=0xbfeda124, envp=0xbfeda13c) at >>> _m3main.mc:4 >>> >>> ------------------------------------------- >>> >>> So it looks like both the main and cloned cvsupd processes were >>> waiting >>> for a response from the kernel call "__kernel_vsyscall ()". Under >>> what >>> condition will this happen? Am I doing something wrong here? >>> >>> -- >>> Ticket URL: >>> CM3 >>> Critical Mass Modula3 Compiler >>> >>> >>> ----- End forwarded message ----- >>> >>> >>> -- >>> Olaf Wagner -- elego Software Solutions GmbH >>> Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, G >>> ermany >>> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 >>> http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: >>> Berlin >>> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: >>> DE163214194 >>> >> >> > > > > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germ > any > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Be > rlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: > DE163214194 > From jay.krell at cornell.edu Sat Jan 2 22:42:22 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 2 Jan 2010 21:42:22 +0000 Subject: [M3devel] Fwd: [CM3] #1080: CVSUPD server hangs if used with -C option In-Reply-To: <8DB9B34C-2F82-4AE7-ADC4-100F01C5F874@cs.purdue.edu> References: <20091229184748.frhga784gkk4cosg@mail.elegosoft.com>, <726BCE28-8561-40BF-BFBD-F96EC4151B50@cs.purdue.edu>, <20100102115406.ck9y12tv4okcoso8@mail.elegosoft.com>, <8DB9B34C-2F82-4AE7-ADC4-100F01C5F874@cs.purdue.edu> Message-ID: > It must have been working relatively recently. This is probably the first time it has been tested since getting into our tree. - Jay > From: hosking at cs.purdue.edu > To: wagner at elegosoft.com > Date: Sat, 2 Jan 2010 13:35:59 -0600 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] Fwd: [CM3] #1080: CVSUPD server hangs if used with -C option > > So, what's changed recently to break this? It must have been working > relatively recently. > > Sent from my iPhone > > On Jan 2, 2010, at 4:54 AM, Olaf Wagner wrote: > > > Quoting Tony Hosking : > > > >> What does -C do? > > > > Make it a server process. From the manual: > > > > -C maxClients > > Limits the number of simultaneous clients to > > maxClients. > > Clients beyond the specified maximum are politely > > refused > > service. > > > > If this option is not specified, cvsupd serves one > > client in > > the foreground and then exits. > > > > Olaf > > > >> On 29 Dec 2009, at 12:47, Olaf Wagner wrote: > >> > >>> Any ideas? Interaction problem between threads and select? > >>> > >>> Olaf > >>> > >>> ----- Forwarded message from bugs at elego.de ----- > >>> Date: Tue, 29 Dec 2009 16:23:23 -0000 > >>> From: CM3 > >>> Reply-To: CM3 > >>> Subject: [CM3] #1080: CVSUPD server hangs if used with -C option > >>> To: @MISSING_DOMAIN > >>> > >>> #1080: CVSUPD server hangs if used with -C option > >>> ----------------------------- > >>> +---------------------------------------------- > >>> Reporter: rajeshvadivelu | Owner: wagner > >>> Type: sw-bug | Status: new > >>> Priority: high | Milestone: > >>> Component: sys | Version: 5.8-RC3 > >>> Severity: critical | Keywords: > >>> Relnote: | Confidential: no > >>> Org: Collabnet | Estimatedhours: 0 > >>> Hours: 0 | Billable: 0 > >>> Totalhours: 0 | > >>> ----------------------------- > >>> +---------------------------------------------- > >>> Htr: > >>> Install cvsup from cm3-bin-ws-cvsup-LINUXLIBC6-5.8.4-RC4.tgz > >>> package. > >>> > >>> Start the cvsupd server with -C option > >>> > >>> ./cvsupd -b /data/cvsupd -C 2 > >>> > >>> Try cvsup client to connect to the sever > >>> > >>> ./cvsup -g -L 2 /tmp/cvsupd.cfg > >>> > >>> The client connection will hang and after sometime we will get > >>> "Inactivity timeout" > >>> > >>> > >>> Fix: > >>> > >>> > >>> > >>> Env: > >>> > >>> > >>> ----------------------------- > >>> +---------------------------------------------- > >>> In a RHEL5 32bit box I was trying to run cvsupd server to mirror > >>> my cvs > >>> repo. I did used cm3-bin-ws-cvsup-LINUXLIBC6-5.8.4-RC4.tgz to get > >>> the > >>> cvsup installed. > >>> > >>> The server starts find and there was no issues if I start the server > >>> without -C option. > >>> > >>> Starting cvsupd server without -C option > >>> > >>> $ ./cvsupd -b /u2/site/data/cvsupd > >>> 2009.12.29 21:31:05 IST [6225]: CVSup server started > >>> 2009.12.29 21:31:05 IST [6225]: Software version: 2009-08-30 > >>> 21:02:46 > >>> 2009.12.29 21:31:05 IST [6225]: Protocol version: 17.0 > >>> 2009.12.29 21:31:05 IST [6225]: Ready to service requests > >>> > >>> Then I did a client request as below > >>> > >>> $ ./cvsup -g -L 2 /tmp/cvsupd.cfg > >>> Parsing supfile "/tmp/cvsupd.cfg" > >>> Connecting to myserver.com > >>> Connected to myserver.com > >>> Rejected by server: Access denied > >>> Will retry at 21:37:09 > >>> > >>> So the request was successful and I get a valid error message at the > >>> client. > >>> > >>> But when I start the server with -C option like the one as below, > >>> requests > >>> from client are hanging and eventually getting "Inactivity > >>> timeout" after > >>> sometime. > >>> > >>> $ ./cvsupd -b /u2/site/data/cvsupd -C 2 > >>> > >>> When ever a new client connection was made, this daemon clones > >>> another > >>> cvsupd process and it also hangs. So none of the client request were > >>> processed. > >>> > >>> Strace of the main cvsupd server process, when a new client > >>> request was > >>> fired. > >>> > >>> ----------------------------------- > >>> select(4, [3], [], [3], {0, 39000}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 1 (in [3], left {0, > >>> 553000}) > >>> accept(3, {sa_family=AF_INET, sin_port=htons(51221), > >>> sin_addr=inet_addr("208.75.198.60")}, [16]) = 6 > >>> setsockopt(6, SOL_SOCKET, SO_LINGER, {onoff=1, linger=1}, 8) = 0 > >>> setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0 > >>> fcntl64(6, F_GETFL) = 0x2 (flags O_RDWR) > >>> fcntl64(6, F_SETFL, O_RDWR|O_NONBLOCK) = 0 > >>> gettimeofday({1262103026, 146476}, NULL) = 0 > >>> open("/u2/site/data/cvsupd/cvsupd.access", O_RDONLY|O_LARGEFILE) = 7 > >>> fstat64(7, {st_mode=S_IFREG|0755, st_size=215, ...}) = 0 > >>> _llseek(7, 0, [0], SEEK_CUR) = 0 > >>> fstat64(7, {st_mode=S_IFREG|0755, st_size=215, ...}) = 0 > >>> close(7) = 0 > >>> gettimeofday({1262103026, 147481}, NULL) = 0 > >>> stat64("/u2/site/data/cvsupd/cvsupd.class", 0xbf809c04) = -1 > >>> ENOENT (No > >>> such file or directory) > >>> write(5, "\0", 1) = 1 > >>> futex(0x91580f0, FUTEX_WAKE, 1) = 1 > >>> futex(0x9158098, FUTEX_WAKE, 1) = 1 > >>> futex(0x91580b8, FUTEX_WAKE, 1) = 1 > >>> futex(0x91580bc, FUTEX_WAIT, 5, NULL) = -1 EAGAIN (Resource > >>> temporarily > >>> unavailable) > >>> futex(0x9158098, FUTEX_WAKE, 1) = 0 > >>> clone(child_stack=0, > >>> flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, > >>> child_tidptr=0xb7f43708) = 6543 > >>> futex(0x915a484, 0x5 /* FUTEX_??? */, 1) = 1 > >>> futex(0x915a460, FUTEX_WAKE, 1) = 1 > >>> futex(0x91580f0, FUTEX_WAKE, 1) = 1 > >>> futex(0x9158098, FUTEX_WAKE, 1) = 1 > >>> futex(0x91580b8, FUTEX_WAKE, 1) = 1 > >>> futex(0x91580bc, FUTEX_WAIT, 7, NULL) = -1 EAGAIN (Resource > >>> temporarily > >>> unavailable) > >>> futex(0x9158098, FUTEX_WAKE, 1) = 0 > >>> close(6) = 0 > >>> accept(3, 0xbf809e44, [16]) = -1 EAGAIN (Resource > >>> temporarily > >>> unavailable) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > >>> > >>> ------------------------------------ > >>> > >>> gdb backtrace of the main cvsupd server process > >>> > >>> ------------------------------------ > >>> > >>> #0 0x00a2a402 in __kernel_vsyscall () > >>> #1 0x0026efb1 in ___newselect_nocancel () from /lib/libc.so.6 > >>> #2 0x00f8965b in Unix__select (nfds=4, readfds=0xb7f9df78, > >>> writefds=0xb7f9df88, exceptfds=0xb7f9df98, timeout=0xbfed9410) at > >>> ../src/unix/Common/UnixC.c:301 > >>> #3 0x00f85f4b in ThreadPThread__XIOWait__CallSelect.779 > >>> (M3_Cwb5VA_nfd=4, > >>> M3_A4bqCj_timeout=0xbfed9410) at > >>> ../src/thread/PTHREAD/ThreadPThread.m3:900 > >>> #4 0x00f85c7a in ThreadPThread__XIOWait (M3_BXP32l_self=0xb7f9400c, > >>> M3_Cwb5VA_fd=3, M3_AicXUJ_read=1 '\001', > >>> M3_CtKayy_interval=1.7976931348623157e+308, M3_AicXUJ_alertable=1 > >>> '\001') > >>> at ../src/thread/PTHREAD/ThreadPThread.m3:936 > >>> #5 0x00f8589d in SchedulerPosix__IOAlertWait (M3_Cwb5VA_fd=3, > >>> M3_AicXUJ_read=1 '\001', M3_CtKayy_timeoutInterval=-1) at > >>> ../src/thread/PTHREAD/ThreadPThread.m3:854 > >>> #6 0x00e4b499 in TCPMisc__AcceptFrom (M3_AahksS_c=0xb7f9ca48, > >>> M3_DoBjMZ_peer=0xbfed9970) at ../src/POSIX/TCP.m3:458 > >>> #7 0x0807bcbf in FSServer__Run (M3_DS26rk_self=0xb7f9c9fc) at > >>> ../src/FSServer.m3:153 > >>> #8 0x080934fd in Main_M3 (M3_AcxOUs_mode=1) at ../src/Main.m3:336 > >>> #9 0x00f717c8 in RTLinker__RunMainBody (M3_DjPxE3_m=0x80a11a0) at > >>> ../src/runtime/common/RTLinker.m3:399 > >>> #10 0x00f70b82 in RTLinker__AddUnitI (M3_DjPxE3_m=0x80a11a0) at > >>> ../src/runtime/common/RTLinker.m3:113 > >>> #11 0x00f70c10 in RTLinker__AddUnit (M3_DjPxE5_b=0x8090f4e) at > >>> ../src/runtime/common/RTLinker.m3:122 > >>> #12 0x0804db1e in main (argc=5, argv=0xbfeda124, envp=0xbfeda13c) at > >>> _m3main.mc:4 > >>> ------------------------------------------------ > >>> > >>> > >>> strace of the cloned cvsupd process > >>> > >>> ----------------------------------- > >>> > >>> futex(0x91580bc, FUTEX_WAIT, 3, NULL > >>> > >>> ----------------------------------- > >>> > >>> gdb backtrace of the cloned cvsupd process > >>> > >>> ----------------------------------- > >>> > >>> #0 0x00a2a402 in __kernel_vsyscall () > >>> #1 0x00320146 in pthread_cond_wait@@GLIBC_2.3.2 () from > >>> /lib/libpthread.so.0 > >>> #2 0x00f886e6 in ThreadPThread__pthread_cond_wait (cond=0x89c60b8, > >>> mutex=0x89c6098) at ../src/thread/PTHREAD/ThreadPThreadC.c:326 > >>> #3 0x00f81d9d in ThreadPThread__XWait (M3_BXP32l_self=0xb7f9400c, > >>> M3_AYIbX3_m=0xb7f9c8d8, M3_Bl0jv4_c=0xb7f9c8f4, > >>> M3_AicXUJ_alertable=0 > >>> '\0') at ../src/thread/PTHREAD/ThreadPThread.m3:238 > >>> #4 0x00f821ae in Thread__Wait (M3_AYIbX3_m=0xb7f9c8d8, > >>> M3_Bl0jv4_c=0xb7f9c8f4) at ../src/thread/PTHREAD/ > >>> ThreadPThread.m3:280 > >>> #5 0x00bd4e14 in SigHandler__ChangeState (M3_BnMAgS_d=0xb7f9c4bc, > >>> M3_AkN0P6_state=2 '\002') at ../src/SigHandler.m3:105 > >>> #6 0x00bd5ba6 in SigHandler__ShutDown () at ../src/ > >>> SigHandler.m3:243 > >>> #7 0x0807cbac in FSServer_M3_LINE_230.718 (L_2=0xbfed95d0) at > >>> ../src/FSServer.m3:231 > >>> #8 0x0807c956 in FSServer__Run (M3_DS26rk_self=0xb7f9c9fc) at > >>> ../src/FSServer.m3:227 > >>> #9 0x080934fd in Main_M3 (M3_AcxOUs_mode=1) at ../src/Main.m3:336 > >>> #10 0x00f717c8 in RTLinker__RunMainBody (M3_DjPxE3_m=0x80a11a0) at > >>> ../src/runtime/common/RTLinker.m3:399 > >>> #11 0x00f70b82 in RTLinker__AddUnitI (M3_DjPxE3_m=0x80a11a0) at > >>> ../src/runtime/common/RTLinker.m3:113 > >>> #12 0x00f70c10 in RTLinker__AddUnit (M3_DjPxE5_b=0x8090f4e) at > >>> ../src/runtime/common/RTLinker.m3:122 > >>> #13 0x0804db1e in main (argc=5, argv=0xbfeda124, envp=0xbfeda13c) at > >>> _m3main.mc:4 > >>> > >>> ------------------------------------------- > >>> > >>> So it looks like both the main and cloned cvsupd processes were > >>> waiting > >>> for a response from the kernel call "__kernel_vsyscall ()". Under > >>> what > >>> condition will this happen? Am I doing something wrong here? > >>> > >>> -- > >>> Ticket URL: > >>> CM3 > >>> Critical Mass Modula3 Compiler > >>> > >>> > >>> ----- End forwarded message ----- > >>> > >>> > >>> -- > >>> Olaf Wagner -- elego Software Solutions GmbH > >>> Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, G > >>> ermany > >>> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > >>> http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: > >>> Berlin > >>> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: > >>> DE163214194 > >>> > >> > >> > > > > > > > > -- > > Olaf Wagner -- elego Software Solutions GmbH > > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germ > > any > > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Be > > rlin > > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: > > DE163214194 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 3 17:48:05 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sun, 3 Jan 2010 11:48:05 -0500 Subject: [M3devel] Fwd: [CM3] #1080: CVSUPD server hangs if used with -C option In-Reply-To: References: <20091229184748.frhga784gkk4cosg@mail.elegosoft.com>, <726BCE28-8561-40BF-BFBD-F96EC4151B50@cs.purdue.edu>, <20100102115406.ck9y12tv4okcoso8@mail.elegosoft.com>, <8DB9B34C-2F82-4AE7-ADC4-100F01C5F874@cs.purdue.edu> Message-ID: Can someone try with user threading to see if it is something in thread waiting? Sent from my iPhone On Jan 2, 2010, at 4:42 PM, Jay K wrote: > > It must have been working relatively recently. > > This is probably the first time it has been tested since getting > into our tree. > > - Jay > > > From: hosking at cs.purdue.edu > > To: wagner at elegosoft.com > > Date: Sat, 2 Jan 2010 13:35:59 -0600 > > CC: m3devel at elegosoft.com > > Subject: Re: [M3devel] Fwd: [CM3] #1080: CVSUPD server hangs if > used with -C option > > > > So, what's changed recently to break this? It must have been working > > relatively recently. > > > > Sent from my iPhone > > > > On Jan 2, 2010, at 4:54 AM, Olaf Wagner > wrote: > > > > > Quoting Tony Hosking : > > > > > >> What does -C do? > > > > > > Make it a server process. From the manual: > > > > > > -C maxClients > > > Limits the number of simultaneous clients to > > > maxClients. > > > Clients beyond the specified maximum are politely > > > refused > > > service. > > > > > > If this option is not specified, cvsupd serves one > > > client in > > > the foreground and then exits. > > > > > > Olaf > > > > > >> On 29 Dec 2009, at 12:47, Olaf Wagner wrote: > > >> > > >>> Any ideas? Interaction problem between threads and select? > > >>> > > >>> Olaf > > >>> > > >>> ----- Forwarded message from bugs at elego.de ----- > > >>> Date: Tue, 29 Dec 2009 16:23:23 -0000 > > >>> From: CM3 > > >>> Reply-To: CM3 > > >>> Subject: [CM3] #1080: CVSUPD server hangs if used with -C option > > >>> To: @MISSING_DOMAIN > > >>> > > >>> #1080: CVSUPD server hangs if used with -C option > > >>> ----------------------------- > > >>> +---------------------------------------------- > > >>> Reporter: rajeshvadivelu | Owner: wagner > > >>> Type: sw-bug | Status: new > > >>> Priority: high | Milestone: > > >>> Component: sys | Version: 5.8-RC3 > > >>> Severity: critical | Keywords: > > >>> Relnote: | Confidential: no > > >>> Org: Collabnet | Estimatedhours: 0 > > >>> Hours: 0 | Billable: 0 > > >>> Totalhours: 0 | > > >>> ----------------------------- > > >>> +---------------------------------------------- > > >>> Htr: > > >>> Install cvsup from cm3-bin-ws-cvsup-LINUXLIBC6-5.8.4-RC4.tgz > > >>> package. > > >>> > > >>> Start the cvsupd server with -C option > > >>> > > >>> ./cvsupd -b /data/cvsupd -C 2 > > >>> > > >>> Try cvsup client to connect to the sever > > >>> > > >>> ./cvsup -g -L 2 /tmp/cvsupd.cfg > > >>> > > >>> The client connection will hang and after sometime we will get > > >>> "Inactivity timeout" > > >>> > > >>> > > >>> Fix: > > >>> > > >>> > > >>> > > >>> Env: > > >>> > > >>> > > >>> ----------------------------- > > >>> +---------------------------------------------- > > >>> In a RHEL5 32bit box I was trying to run cvsupd server to mirror > > >>> my cvs > > >>> repo. I did used cm3-bin-ws-cvsup-LINUXLIBC6-5.8.4-RC4.tgz to > get > > >>> the > > >>> cvsup installed. > > >>> > > >>> The server starts find and there was no issues if I start the > server > > >>> without -C option. > > >>> > > >>> Starting cvsupd server without -C option > > >>> > > >>> $ ./cvsupd -b /u2/site/data/cvsupd > > >>> 2009.12.29 21:31:05 IST [6225]: CVSup server started > > >>> 2009.12.29 21:31:05 IST [6225]: Software version: 2009-08-30 > > >>> 21:02:46 > > >>> 2009.12.29 21:31:05 IST [6225]: Protocol version: 17.0 > > >>> 2009.12.29 21:31:05 IST [6225]: Ready to service requests > > >>> > > >>> Then I did a client request as below > > >>> > > >>> $ ./cvsup -g -L 2 /tmp/cvsupd.cfg > > >>> Parsing supfile "/tmp/cvsupd.cfg" > > >>> Connecting to myserver.com > > >>> Connected to myserver.com > > >>> Rejected by server: Access denied > > >>> Will retry at 21:37:09 > > >>> > > >>> So the request was successful and I get a valid error message > at the > > >>> client. > > >>> > > >>> But when I start the server with -C option like the one as > below, > > >>> requests > > >>> from client are hanging and eventually getting "Inactivity > > >>> timeout" after > > >>> sometime. > > >>> > > >>> $ ./cvsupd -b /u2/site/data/cvsupd -C 2 > > >>> > > >>> When ever a new client connection was made, this daemon clones > > >>> another > > >>> cvsupd process and it also hangs. So none of the client > request were > > >>> processed. > > >>> > > >>> Strace of the main cvsupd server process, when a new client > > >>> request was > > >>> fired. > > >>> > > >>> ----------------------------------- > > >>> select(4, [3], [], [3], {0, 39000}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 1 (in [3], left {0, > > >>> 553000}) > > >>> accept(3, {sa_family=AF_INET, sin_port=htons(51221), > > >>> sin_addr=inet_addr("208.75.198.60")}, [16]) = 6 > > >>> setsockopt(6, SOL_SOCKET, SO_LINGER, {onoff=1, linger=1}, 8) = 0 > > >>> setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0 > > >>> fcntl64(6, F_GETFL) = 0x2 (flags O_RDWR) > > >>> fcntl64(6, F_SETFL, O_RDWR|O_NONBLOCK) = 0 > > >>> gettimeofday({1262103026, 146476}, NULL) = 0 > > >>> open("/u2/site/data/cvsupd/cvsupd.access", O_RDONLY| > O_LARGEFILE) = 7 > > >>> fstat64(7, {st_mode=S_IFREG|0755, st_size=215, ...}) = 0 > > >>> _llseek(7, 0, [0], SEEK_CUR) = 0 > > >>> fstat64(7, {st_mode=S_IFREG|0755, st_size=215, ...}) = 0 > > >>> close(7) = 0 > > >>> gettimeofday({1262103026, 147481}, NULL) = 0 > > >>> stat64("/u2/site/data/cvsupd/cvsupd.class", 0xbf809c04) = -1 > > >>> ENOENT (No > > >>> such file or directory) > > >>> write(5, "\0", 1) = 1 > > >>> futex(0x91580f0, FUTEX_WAKE, 1) = 1 > > >>> futex(0x9158098, FUTEX_WAKE, 1) = 1 > > >>> futex(0x91580b8, FUTEX_WAKE, 1) = 1 > > >>> futex(0x91580bc, FUTEX_WAIT, 5, NULL) = -1 EAGAIN (Resource > > >>> temporarily > > >>> unavailable) > > >>> futex(0x9158098, FUTEX_WAKE, 1) = 0 > > >>> clone(child_stack=0, > > >>> flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, > > >>> child_tidptr=0xb7f43708) = 6543 > > >>> futex(0x915a484, 0x5 /* FUTEX_??? */, 1) = 1 > > >>> futex(0x915a460, FUTEX_WAKE, 1) = 1 > > >>> futex(0x91580f0, FUTEX_WAKE, 1) = 1 > > >>> futex(0x9158098, FUTEX_WAKE, 1) = 1 > > >>> futex(0x91580b8, FUTEX_WAKE, 1) = 1 > > >>> futex(0x91580bc, FUTEX_WAIT, 7, NULL) = -1 EAGAIN (Resource > > >>> temporarily > > >>> unavailable) > > >>> futex(0x9158098, FUTEX_WAKE, 1) = 0 > > >>> close(6) = 0 > > >>> accept(3, 0xbf809e44, [16]) = -1 EAGAIN (Resource > > >>> temporarily > > >>> unavailable) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> select(4, [3], [], [3], {1, 0}) = 0 (Timeout) > > >>> > > >>> ------------------------------------ > > >>> > > >>> gdb backtrace of the main cvsupd server process > > >>> > > >>> ------------------------------------ > > >>> > > >>> #0 0x00a2a402 in __kernel_vsyscall () > > >>> #1 0x0026efb1 in ___newselect_nocancel () from /lib/libc.so.6 > > >>> #2 0x00f8965b in Unix__select (nfds=4, readfds=0xb7f9df78, > > >>> writefds=0xb7f9df88, exceptfds=0xb7f9df98, timeout=0xbfed9410) > at > > >>> ../src/unix/Common/UnixC.c:301 > > >>> #3 0x00f85f4b in ThreadPThread__XIOWait__CallSelect.779 > > >>> (M3_Cwb5VA_nfd=4, > > >>> M3_A4bqCj_timeout=0xbfed9410) at > > >>> ../src/thread/PTHREAD/ThreadPThread.m3:900 > > >>> #4 0x00f85c7a in ThreadPThread__XIOWait > (M3_BXP32l_self=0xb7f9400c, > > >>> M3_Cwb5VA_fd=3, M3_AicXUJ_read=1 '\001', > > >>> M3_CtKayy_interval=1.7976931348623157e+308, > M3_AicXUJ_alertable=1 > > >>> '\001') > > >>> at ../src/thread/PTHREAD/ThreadPThread.m3:936 > > >>> #5 0x00f8589d in SchedulerPosix__IOAlertWait (M3_Cwb5VA_fd=3, > > >>> M3_AicXUJ_read=1 '\001', M3_CtKayy_timeoutInterval=-1) at > > >>> ../src/thread/PTHREAD/ThreadPThread.m3:854 > > >>> #6 0x00e4b499 in TCPMisc__AcceptFrom (M3_AahksS_c=0xb7f9ca48, > > >>> M3_DoBjMZ_peer=0xbfed9970) at ../src/POSIX/TCP.m3:458 > > >>> #7 0x0807bcbf in FSServer__Run (M3_DS26rk_self=0xb7f9c9fc) at > > >>> ../src/FSServer.m3:153 > > >>> #8 0x080934fd in Main_M3 (M3_AcxOUs_mode=1) at ../src/ > Main.m3:336 > > >>> #9 0x00f717c8 in RTLinker__RunMainBody (M3_DjPxE3_m=0x80a11a0) > at > > >>> ../src/runtime/common/RTLinker.m3:399 > > >>> #10 0x00f70b82 in RTLinker__AddUnitI (M3_DjPxE3_m=0x80a11a0) at > > >>> ../src/runtime/common/RTLinker.m3:113 > > >>> #11 0x00f70c10 in RTLinker__AddUnit (M3_DjPxE5_b=0x8090f4e) at > > >>> ../src/runtime/common/RTLinker.m3:122 > > >>> #12 0x0804db1e in main (argc=5, argv=0xbfeda124, > envp=0xbfeda13c) at > > >>> _m3main.mc:4 > > >>> ------------------------------------------------ > > >>> > > >>> > > >>> strace of the cloned cvsupd process > > >>> > > >>> ----------------------------------- > > >>> > > >>> futex(0x91580bc, FUTEX_WAIT, 3, NULL > > >>> > > >>> ----------------------------------- > > >>> > > >>> gdb backtrace of the cloned cvsupd process > > >>> > > >>> ----------------------------------- > > >>> > > >>> #0 0x00a2a402 in __kernel_vsyscall () > > >>> #1 0x00320146 in pthread_cond_wait@@GLIBC_2.3.2 () from > > >>> /lib/libpthread.so.0 > > >>> #2 0x00f886e6 in ThreadPThread__pthread_cond_wait > (cond=0x89c60b8, > > >>> mutex=0x89c6098) at ../src/thread/PTHREAD/ThreadPThreadC.c:326 > > >>> #3 0x00f81d9d in ThreadPThread__XWait > (M3_BXP32l_self=0xb7f9400c, > > >>> M3_AYIbX3_m=0xb7f9c8d8, M3_Bl0jv4_c=0xb7f9c8f4, > > >>> M3_AicXUJ_alertable=0 > > >>> '\0') at ../src/thread/PTHREAD/ThreadPThread.m3:238 > > >>> #4 0x00f821ae in Thread__Wait (M3_AYIbX3_m=0xb7f9c8d8, > > >>> M3_Bl0jv4_c=0xb7f9c8f4) at ../src/thread/PTHREAD/ > > >>> ThreadPThread.m3:280 > > >>> #5 0x00bd4e14 in SigHandler__ChangeState > (M3_BnMAgS_d=0xb7f9c4bc, > > >>> M3_AkN0P6_state=2 '\002') at ../src/SigHandler.m3:105 > > >>> #6 0x00bd5ba6 in SigHandler__ShutDown () at ../src/ > > >>> SigHandler.m3:243 > > >>> #7 0x0807cbac in FSServer_M3_LINE_230.718 (L_2=0xbfed95d0) at > > >>> ../src/FSServer.m3:231 > > >>> #8 0x0807c956 in FSServer__Run (M3_DS26rk_self=0xb7f9c9fc) at > > >>> ../src/FSServer.m3:227 > > >>> #9 0x080934fd in Main_M3 (M3_AcxOUs_mode=1) at ../src/ > Main.m3:336 > > >>> #10 0x00f717c8 in RTLinker__RunMainBody > (M3_DjPxE3_m=0x80a11a0) at > > >>> ../src/runtime/common/RTLinker.m3:399 > > >>> #11 0x00f70b82 in RTLinker__AddUnitI (M3_DjPxE3_m=0x80a11a0) at > > >>> ../src/runtime/common/RTLinker.m3:113 > > >>> #12 0x00f70c10 in RTLinker__AddUnit (M3_DjPxE5_b=0x8090f4e) at > > >>> ../src/runtime/common/RTLinker.m3:122 > > >>> #13 0x0804db1e in main (argc=5, argv=0xbfeda124, > envp=0xbfeda13c) at > > >>> _m3main.mc:4 > > >>> > > >>> ------------------------------------------- > > >>> > > >>> So it looks like both the main and cloned cvsupd processes were > > >>> waiting > > >>> for a response from the kernel call "__kernel_vsyscall ()". > Under > > >>> what > > >>> condition will this happen? Am I doing something wrong here? > > >>> > > >>> -- > > >>> Ticket URL: > > >>> CM3 > > >>> Critical Mass Modula3 Compiler > > >>> > > >>> > > >>> ----- End forwarded message ----- > > >>> > > >>> > > >>> -- > > >>> Olaf Wagner -- elego Software Solutions GmbH > > >>> Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, G > > >>> ermany > > >>> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > > >>> http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sit > z: > > >>> Berlin > > >>> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: > > >>> DE163214194 > > >>> > > >> > > >> > > > > > > > > > > > > -- > > > Olaf Wagner -- elego Software Solutions GmbH > > > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germ > > > any > > > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > > > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: > Be > > > rlin > > > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: > > > DE163214194 > > > From hendrik at topoi.pooq.com Mon Jan 4 05:12:22 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Sun, 3 Jan 2010 23:12:22 -0500 Subject: [M3devel] C generating back end In-Reply-To: <0B27C390-09BA-4B09-9EE2-72602331FB94@cs.purdue.edu> References: <0B27C390-09BA-4B09-9EE2-72602331FB94@cs.purdue.edu> Message-ID: <20100104041222.GD7180@topoi.pooq.com> On Fri, Jan 01, 2010 at 06:42:34PM -0500, Tony Hosking wrote: > On 1 Jan 2010, at 18:05, Jay K wrote: > > > Fyi I finally looked at the 2.x implementation and the outputing of > > C was implemented fairly directly at the m3front layer. > > There wasn't the "M3CG" stuff. > > > > > > Thus, the "easiest" way to get back such functionality would > > probably be to "interleave" the old code and the new code within m3front. > > I'd like to avoid that sort of interleaving. > > > The "cleaner" way is probably to implement a new M3CG though and > > leave m3front unchanged. > > This is a much better plan. > > > I still think generating portable C a great way to achieve portability. > > Better yet maybe, generate C++ and use its exception handling feature. There's a potential advantage in generating C++: it might be possible to interoperate with C++. Whether it's feasible to make the C++ readable and its contents stable is a big question, though. -- hendrik From jay.krell at cornell.edu Mon Jan 4 12:50:47 2010 From: jay.krell at cornell.edu (Jay K) Date: Mon, 4 Jan 2010 11:50:47 +0000 Subject: [M3devel] exception handling and signal mask? Message-ID: "try" isn't supposed to save the signal mask, right? I mean..like..finally doesn't restore it, right? Nor does I suspect raise/except. Specifically: Darwin. There should be underscores in Target.m3 there? Some of this /might/ be might fault. In particular I was unaware of this signal mask thing and its relationship to setjmp/longjmp. Furthermore, um... you know (or if you don't, I'll tell you): Many platforms have two versions of setjmp/longjmp. One saves/restore the signal mask. One does not. Sometimes I think it is via some #define to "steer" /usr/include/setjmp.h. Sometimes, I'm certain, it is setjmp vs. _setjmp, longjmp vs. _longjmp. And then, furthermore, every system I've looked into recently except for NT offers sigsetjmp/siglongjmp. Their semantics when present are consistent. Albeit less efficient. sigsetjmp takes an extra integer (boolean) indicating of the signal mask should be saved. They use sigjmp_buf instead of jmp_buf, which is sometimes identical, sometimes one or two integers larger, or possibly even larger, depending on the size of the signal mask. So...for the cost of sometimes enlarging the jmpbuf, and for the cost of passing the extra integer 0, maybe we should use sigsetjmp on all Unix systems? I believe the Solaris documentation warns about the "less clearly named functions" (my wording) changing semantic..though I kind of doubt they can do that.. Not saving the signal mask is potentially much faster, as it might require a syscall to get. (Though I also wonder if it can't be a special thread local, like at a fixed offset from FS or GS as NT does it.) I'll go ahead and try just the smaller change of having Darwin use _setjmp instead of setjmp. Not going ahead with sigsetjmp. Just yet. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Mon Jan 4 16:20:53 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 4 Jan 2010 10:20:53 -0500 Subject: [M3devel] exception handling and signal mask? In-Reply-To: References: Message-ID: <27F530A4-62ED-490E-83CA-E3045103B4E1@cs.purdue.edu> On 4 Jan 2010, at 06:50, Jay K wrote: > "try" isn't supposed to save the signal mask, right? > I mean..like..finally doesn't restore it, right? > Nor does I suspect raise/except. Good question. No, exception handling mechanisms should not be responsible for this. The design principle is usually to make TRY as fast as possible at the expense of the exceptional case. Signal mask restoration should be programmed explicitly in a FINALLY clause. > Specifically: Darwin. > There should be underscores in Target.m3 there? So, short answer on Darwin is to prefer _setjmp/_longjmp. Same on all other platforms. > > > Some of this /might/ be might fault. > In particular I was unaware of this signal mask thing and its relationship to setjmp/longjmp. > > > Furthermore, um... you know (or if you don't, I'll tell you): > > > Many platforms have two versions of setjmp/longjmp. > One saves/restore the signal mask. One does not. > Sometimes I think it is via some #define to "steer" /usr/include/setjmp.h. > Sometimes, I'm certain, it is setjmp vs. _setjmp, longjmp vs. _longjmp. > > And then, furthermore, every system I've looked into recently except for NT > offers sigsetjmp/siglongjmp. > Their semantics when present are consistent. > Albeit less efficient. > sigsetjmp takes an extra integer (boolean) indicating of the signal mask should be saved. > They use sigjmp_buf instead of jmp_buf, which is sometimes identical, sometimes one or two integers larger, or possibly even larger, depending on the size of the signal mask. > > So...for the cost of sometimes enlarging the jmpbuf, and for the cost of passing the extra integer 0, maybe we should use sigsetjmp on all Unix systems? I believe the Solaris documentation warns about the "less clearly named functions" (my wording) changing semantic..though I kind of doubt they can do that.. > > > Not saving the signal mask is potentially much faster, as it might require a syscall to get. > (Though I also wonder if it can't be a special thread local, like at a fixed offset from FS or GS as NT does it.) > > > I'll go ahead and try just the smaller change of having Darwin use _setjmp instead of setjmp. > Not going ahead with sigsetjmp. Just yet. > > - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Wed Jan 6 03:59:42 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 5 Jan 2010 21:59:42 -0500 Subject: [M3devel] A "radical" proposal: drop LONGINT Message-ID: Now that Jay has carefully refactored all the C-dependent code, I'd like to pose the following question. What say we clean things up, revert to the original clean language definition, and eliminate LONGINT? It was only ever there for compatibility with C headers anyway, and these have all now been nicely abstracted away. The only remaining uses of LONGINT are in defining Modula-3 alternatives for C structs. These can be rewritten to something other than LONGINT. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Jan 6 07:12:17 2010 From: jay.krell at cornell.edu (Jay K) Date: Wed, 6 Jan 2010 06:12:17 +0000 Subject: [M3devel] A "radical" proposal: drop LONGINT In-Reply-To: References: Message-ID: Can I still have: TYPE INT64 = BITS 64 FOR [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; or TYPE INT64 = [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; ? defined in an interface, not in the language? If so, probably ok. (And can I also somehow get: TYPE UINT32 = BITS 32 FOR [0..16_FFFFFFFF]; TYPE UINT64 = BITS 64 FOR [0..16_FFFFFFFFFFFFFFFF]; or TYPE UINT32 = [0..16_FFFFFFFF]; TYPE UINT64 = [0..16_FFFFFFFFFFFFFFFF]; ? ) Even on 32 bit machines? I know there is interface Word. And then, what is the difference between: on 32bit: INTEGER vs. [16_80000000..16_7FFFFFFF] CARDINAL vs. [0..16_7FFFFFFF] on 64bit: INTEGER vs. [16_8000000000000000..16_7FFFFFFFFFFFFFFF] CARDINAL vs. [0..16_7FFFFFFFFFFFFFFF] Any at all? Just that array sizes are cardinal? I don't know much about the language issues, but dealing with 64bit integers in 32bit Modula-3 ought to be about as easy and efficient as dealing with them in C and C++ I think. Hm..and why? Well..file sizes should be represented as 64bit integers, though they aren't yet..it seems to be a significant interface breaking change..though maybe range types aren't where LONGINT would be? I'll have to try that.. - Jay ________________________________ > From: hosking at cs.purdue.edu > Date: Tue, 5 Jan 2010 21:59:42 -0500 > To: m3devel at elegosoft.com > Subject: [M3devel] A "radical" proposal: drop LONGINT > > > > Now that Jay has carefully refactored all the C-dependent code, I'd like to pose the following question. What say we clean things up, revert to the original clean language definition, and eliminate LONGINT? It was only ever there for compatibility with C headers anyway, and these have all now been nicely abstracted away. The only remaining uses of LONGINT are in defining Modula-3 alternatives for C structs. These can be rewritten to something other than LONGINT. > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 From hosking at cs.purdue.edu Wed Jan 6 08:06:34 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 6 Jan 2010 02:06:34 -0500 Subject: [M3devel] A "radical" proposal: drop LONGINT In-Reply-To: References: Message-ID: What do you need those 64-bit types for on 32-bit machines? On 32-bit machines INTEGER would still be 32-bit. On 6 Jan 2010, at 01:12, Jay K wrote: > > Can I still have: > TYPE INT64 = BITS 64 FOR [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; > or > TYPE INT64 = [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; > ? defined in an interface, not in the language? > > > If so, probably ok. > > > (And can I also somehow get: > TYPE UINT32 = BITS 32 FOR [0..16_FFFFFFFF]; > TYPE UINT64 = BITS 64 FOR [0..16_FFFFFFFFFFFFFFFF]; > or > TYPE UINT32 = [0..16_FFFFFFFF]; > TYPE UINT64 = [0..16_FFFFFFFFFFFFFFFF]; > ? > ) > > > Even on 32 bit machines? > > > I know there is interface Word. > > > And then, what is the difference between: > > > on 32bit: > INTEGER vs. [16_80000000..16_7FFFFFFF] > CARDINAL vs. [0..16_7FFFFFFF] > > > on 64bit: > INTEGER vs. [16_8000000000000000..16_7FFFFFFFFFFFFFFF] > CARDINAL vs. [0..16_7FFFFFFFFFFFFFFF] > > > Any at all? > Just that array sizes are cardinal? > > > I don't know much about the language issues, but dealing with 64bit integers in 32bit Modula-3 ought to be about as easy and efficient as dealing with them in C and C++ I think. Hm..and why? Well..file sizes should be represented as 64bit integers, though they aren't yet..it seems to be a significant interface breaking change..though maybe range types aren't where LONGINT would be? I'll have to try that.. > > > - Jay > > > ________________________________ >> From: hosking at cs.purdue.edu >> Date: Tue, 5 Jan 2010 21:59:42 -0500 >> To: m3devel at elegosoft.com >> Subject: [M3devel] A "radical" proposal: drop LONGINT >> >> >> >> Now that Jay has carefully refactored all the C-dependent code, I'd like to pose the following question. What say we clean things up, revert to the original clean language definition, and eliminate LONGINT? It was only ever there for compatibility with C headers anyway, and these have all now been nicely abstracted away. The only remaining uses of LONGINT are in defining Modula-3 alternatives for C structs. These can be rewritten to something other than LONGINT. >> >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Wed Jan 6 08:11:53 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 6 Jan 2010 02:11:53 -0500 Subject: [M3devel] A "radical" proposal: drop LONGINT In-Reply-To: References: Message-ID: <84C08978-0083-4986-83D0-B3F255B5D526@cs.purdue.edu> PS Any type that *requires* 64-bit could be represented as: ARRAY [0..1] OF BITS 32 FOR [0..16_FFFFFFFF] or RECORD x, y: BITS 32 FOR [0..16_FFFFFFFF] END Is there ever a need to treat these as 64-bit integers? On 6 Jan 2010, at 02:06, Tony Hosking wrote: > What do you need those 64-bit types for on 32-bit machines? On 32-bit machines INTEGER would still be 32-bit. > > On 6 Jan 2010, at 01:12, Jay K wrote: > >> >> Can I still have: >> TYPE INT64 = BITS 64 FOR [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; >> or >> TYPE INT64 = [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; >> ? defined in an interface, not in the language? >> >> >> If so, probably ok. >> >> >> (And can I also somehow get: >> TYPE UINT32 = BITS 32 FOR [0..16_FFFFFFFF]; >> TYPE UINT64 = BITS 64 FOR [0..16_FFFFFFFFFFFFFFFF]; >> or >> TYPE UINT32 = [0..16_FFFFFFFF]; >> TYPE UINT64 = [0..16_FFFFFFFFFFFFFFFF]; >> ? >> ) >> >> >> Even on 32 bit machines? >> >> >> I know there is interface Word. >> >> >> And then, what is the difference between: >> >> >> on 32bit: >> INTEGER vs. [16_80000000..16_7FFFFFFF] >> CARDINAL vs. [0..16_7FFFFFFF] >> >> >> on 64bit: >> INTEGER vs. [16_8000000000000000..16_7FFFFFFFFFFFFFFF] >> CARDINAL vs. [0..16_7FFFFFFFFFFFFFFF] >> >> >> Any at all? >> Just that array sizes are cardinal? >> >> >> I don't know much about the language issues, but dealing with 64bit integers in 32bit Modula-3 ought to be about as easy and efficient as dealing with them in C and C++ I think. Hm..and why? Well..file sizes should be represented as 64bit integers, though they aren't yet..it seems to be a significant interface breaking change..though maybe range types aren't where LONGINT would be? I'll have to try that.. >> >> >> - Jay >> >> >> ________________________________ >>> From: hosking at cs.purdue.edu >>> Date: Tue, 5 Jan 2010 21:59:42 -0500 >>> To: m3devel at elegosoft.com >>> Subject: [M3devel] A "radical" proposal: drop LONGINT >>> >>> >>> >>> Now that Jay has carefully refactored all the C-dependent code, I'd like to pose the following question. What say we clean things up, revert to the original clean language definition, and eliminate LONGINT? It was only ever there for compatibility with C headers anyway, and these have all now been nicely abstracted away. The only remaining uses of LONGINT are in defining Modula-3 alternatives for C structs. These can be rewritten to something other than LONGINT. >>> >>> >>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>> 305 N. University Street | West Lafayette | IN 47907 | USA >>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Jan 6 09:01:12 2010 From: jay.krell at cornell.edu (Jay K) Date: Wed, 6 Jan 2010 08:01:12 +0000 Subject: [M3devel] A "radical" proposal: drop LONGINT In-Reply-To: <84C08978-0083-4986-83D0-B3F255B5D526@cs.purdue.edu> References: , , , <84C08978-0083-4986-83D0-B3F255B5D526@cs.purdue.edu> Message-ID: Well..to be sure to get good codegen, given that the gcc backend and every C compiler these days supports 64bit integers "directly" (to the best of their ability, sometimes function calls are involved). As well, you know, to get those nice operators +, -, *, /, :=, =, <>. I realize it largely comes down to a matter of "convenient builtin special syntax" vs. "user defined types and inconvenient function calls". Here does lie the argument that I should be able define operators for user defined types, instead just TEXT and INTEGER and sets getting the special powers.. Not to mention inlining via special support in the frontend. (I realize a good backend could do the same). interface int64; T = ARRAY[0..1] OF INTEGER. PROCEDURE +(a,b:T):T; PROCEDURE *(a,b:T):T; PROCEDURE /(a,b:T):T; ? etc... Basically the "builtin" types are always more "convenient" than any user defined types. Only C++ as far as I know really attemps to solve that problem.. - Jay ________________________________ > From: hosking at cs.purdue.edu > Date: Wed, 6 Jan 2010 02:11:53 -0500 > To: hosking at cs.purdue.edu > CC: m3devel at elegosoft.com; jay.krell at cornell.edu > Subject: Re: [M3devel] A "radical" proposal: drop LONGINT > > > > PS Any type that *requires* 64-bit could be represented as: > > ARRAY [0..1] OF BITS 32 FOR [0..16_FFFFFFFF] > > or > > RECORD x, y: BITS 32 FOR [0..16_FFFFFFFF] END > > Is there ever a need to treat these as 64-bit integers? > > On 6 Jan 2010, at 02:06, Tony Hosking wrote: > > What do you need those 64-bit types for on 32-bit machines? On 32-bit machines INTEGER would still be 32-bit. > > On 6 Jan 2010, at 01:12, Jay K wrote: > > > Can I still have: > TYPE INT64 = BITS 64 FOR [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; > or > TYPE INT64 = [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; > ? defined in an interface, not in the language? > > > If so, probably ok. > > > (And can I also somehow get: > TYPE UINT32 = BITS 32 FOR [0..16_FFFFFFFF]; > TYPE UINT64 = BITS 64 FOR [0..16_FFFFFFFFFFFFFFFF]; > or > TYPE UINT32 = [0..16_FFFFFFFF]; > TYPE UINT64 = [0..16_FFFFFFFFFFFFFFFF]; > ? > ) > > > Even on 32 bit machines? > > > I know there is interface Word. > > > And then, what is the difference between: > > > on 32bit: > INTEGER vs. [16_80000000..16_7FFFFFFF] > CARDINAL vs. [0..16_7FFFFFFF] > > > on 64bit: > INTEGER vs. [16_8000000000000000..16_7FFFFFFFFFFFFFFF] > CARDINAL vs. [0..16_7FFFFFFFFFFFFFFF] > > > Any at all? > Just that array sizes are cardinal? > > > I don't know much about the language issues, but dealing with 64bit integers in 32bit Modula-3 ought to be about as easy and efficient as dealing with them in C and C++ I think. Hm..and why? Well..file sizes should be represented as 64bit integers, though they aren't yet..it seems to be a significant interface breaking change..though maybe range types aren't where LONGINT would be? I'll have to try that.. > > > - Jay > > > ________________________________ > From: hosking at cs.purdue.edu > Date: Tue, 5 Jan 2010 21:59:42 -0500 > To: m3devel at elegosoft.com > Subject: [M3devel] A "radical" proposal: drop LONGINT > > > > Now that Jay has carefully refactored all the C-dependent code, I'd like to pose the following question. What say we clean things up, revert to the original clean language definition, and eliminate LONGINT? It was only ever there for compatibility with C headers anyway, and these have all now been nicely abstracted away. The only remaining uses of LONGINT are in defining Modula-3 alternatives for C structs. These can be rewritten to something other than LONGINT. > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > From jay.krell at cornell.edu Wed Jan 6 13:28:02 2010 From: jay.krell at cornell.edu (Jay K) Date: Wed, 6 Jan 2010 12:28:02 +0000 Subject: [M3devel] double double double double checking jmp_buf size/alignment Message-ID: Getting this right is very important. Well, we can overstate but it is wasteful. So anyone with any time, please compile/run this and send the "platform" (uname -a) and the output, thanks. Or look at m3-libs/m3core/src/C/*/Csetjmp.i3 and m3-sys/m3middle/src/Target.m3 and see if all three agree. I have checked a bunch of systems myself but extra checking is good. If you have a system we don't yet or any longer support, those are ok too. (e.g. Alpha_*, ARM_*, MIPS_*, *_Irix, *_VMS, *_Tru64 etc.) #include #include #ifdef __GNUC__ #define ALIGN_OF(x) ((int)(sizeof(struct { char a; x b; }) - sizeof(x))) #else #define ALIGN_OF(x) ((int)__alignof(x)) int main() { printf("%d %d\n", (int)sizeof(jmp_buf), ALIGN_OF(jmp_buf)); return 0; } Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Jan 6 14:17:34 2010 From: jay.krell at cornell.edu (Jay K) Date: Wed, 6 Jan 2010 13:17:34 +0000 Subject: [M3devel] double double double double checking jmp_buf size/alignment Message-ID: Was truncated!..edited slightly to avoid.. From: jay.krell at cornell.edu To: m3devel at elegosoft.com Subject: double double double double checking jmp_buf size/alignment Date: Wed, 6 Jan 2010 12:28:02 +0000 Getting this right is very important. Well, we can overstate but it is wasteful. So anyone with any time, please compile/run this and send the "platform" (uname -a) and the output, thanks. Or look at m3-libs/m3core/src/C/*/Csetjmp.i3 and m3-sys/m3middle/src/Target.m3 and see if all three agree. I have checked a bunch of systems myself but extra checking is good. If you have a system we do not yet or any longer support, those are ok too. (e.g. Alpha_*, ARM_*, MIPS_*, *_Irix, *_VMS, *_Tru64 etc.) #include #include #ifdef __GNUC__ #define ALIGN_OF(x) ((int)(sizeof(struct { char a; x b; }) - sizeof(x))) #else #define ALIGN_OF(x) ((int)__alignof(x)) int main() { printf("%d %d\n", (int)sizeof(jmp_buf), ALIGN_OF(jmp_buf)); return 0; } Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From mika at async.async.caltech.edu Wed Jan 6 17:25:58 2010 From: mika at async.async.caltech.edu (Mika Nystrom) Date: Wed, 06 Jan 2010 08:25:58 -0800 Subject: [M3devel] double double double double checking jmp_buf size/alignment In-Reply-To: References: Message-ID: <20100106162558.7B4101A2079@async.async.caltech.edu> Forgot the #endif there? (81)trs80:~>./a.out 48 4 (82)trs80:~>uname -a FreeBSD trs80.async.caltech.edu 4.11-RELEASE FreeBSD 4.11-RELEASE #3: Mon Nov 21 20:27:08 PST 2005 root at trs80.async.caltech.edu:/usr/src/sys/compile/TRS80 i386 [lapdog:~] mika% cc jay.c [lapdog:~] mika% ./a.out 768 4 [lapdog:~] mika% uname -a Darwin lapdog 8.11.0 Darwin Kernel Version 8.11.0: Wed Oct 10 18:26:00 PDT 2007; root:xnu-792.24.17~1/RELEASE_PPC Power Macintosh powerpc [lapdog:~] mika% Jay K writes: >--_b0fc625a-8a60-4f2b-9394-0f52cc975894_ >Content-Type: text/plain; charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable > > >Was truncated!..edited slightly to avoid.. > > >From: jay.krell at cornell.edu >To: m3devel at elegosoft.com >Subject: double double double double checking jmp_buf size/alignment >Date: Wed=2C 6 Jan 2010 12:28:02 +0000 > > > > > > > > >Getting this right is very important. > Well=2C we can overstate but it is wasteful. > > >So anyone with any time=2C please compile/run this and send the "platform" = >(uname -a) and the output=2C thanks. >Or look at m3-libs/m3core/src/C/*/Csetjmp.i3 and >m3-sys/m3middle/src/Target.m3 and see if all three agree. > > >I have checked a bunch of systems myself but extra checking is good. > > >If you have a system we do not yet or any longer support=2C those are ok to= >o. > (e.g. Alpha_*=2C ARM_*=2C MIPS_*=2C *_Irix=2C *_VMS=2C *_Tru64 etc.) > >=20 >#include >#include > >#ifdef __GNUC__ >#define ALIGN_OF(x) ((int)(sizeof(struct { char a=3B x b=3B }) - sizeof(x))= >) >#else >#define ALIGN_OF(x) ((int)__alignof(x)) > >int main() >{ > printf("%d %d\n"=2C (int)sizeof(jmp_buf)=2C ALIGN_OF(jmp_buf))=3B > return 0=3B >} > > >Thanks=2C > - Jay > = > >--_b0fc625a-8a60-4f2b-9394-0f52cc975894_ >Content-Type: text/html; charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable > > > > > > >Was truncated!..edited slightly to avoid..



g">From: jay.krell at cornell.edu
To: m3devel at elegosoft.com
Subject: dou= >ble double double double checking jmp_buf size/alignment
Date: Wed=2C 6 = >Jan 2010 12:28:02 +0000

> > > > > > >Getting this right is very important.
 =3B Well=2C we can overstate = >but it is wasteful.


So anyone with any time=2C please compile/ru= >n this and send the "platform" (uname -a) and the output=2C thanks.
Or l= >ook at m3-libs/m3core/src/C/*/Csetjmp.i3 and
m3-sys/m3middle/src/Target.= >m3 and see if all three agree.


I have checked a bunch of systems= > myself but extra checking is good.


If you have a system we do n= >ot yet or any longer support=2C those are ok too.
 =3B(e.g. Alpha_*= >=2C ARM_*=2C MIPS_*=2C *_Irix=2C *_VMS=2C *_Tru64 etc.)

 =3B
= >#include <=3Bsetjmp.h>=3B
#include <=3Bstdio.h>=3B

#ifdef= > __GNUC__
#define ALIGN_OF(x) ((int)(sizeof(struct { char a=3B x b=3B })= > - sizeof(x)))
#else
#define ALIGN_OF(x) ((int)__alignof(x))

i= >nt main()
{
 =3B printf("%d %d\n"=2C (int)sizeof(jmp_buf)=2C ALIG= >N_OF(jmp_buf))=3B
 =3B return 0=3B
}


Thanks=2C
&nbs= >p=3B- Jay
>= > >--_b0fc625a-8a60-4f2b-9394-0f52cc975894_-- From hosking at cs.purdue.edu Wed Jan 6 17:42:56 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 6 Jan 2010 11:42:56 -0500 Subject: [M3devel] A "radical" proposal: drop LONGINT In-Reply-To: References: , , , <84C08978-0083-4986-83D0-B3F255B5D526@cs.purdue.edu> Message-ID: <1746EDCD-2BBE-4A4B-BACB-7EED5FEB29D2@cs.purdue.edu> But my question is what are the current use-cases for LONGINT? Do they justify retaining it? On 6 Jan 2010, at 03:01, Jay K wrote: > > Well..to be sure to get good codegen, given that the gcc backend and every C compiler these days supports 64bit integers "directly" (to the best of their ability, sometimes function calls are involved). > > > As well, you know, to get those nice operators +, -, *, /, :=, =, <>. > > > I realize it largely comes down to a matter of "convenient builtin special syntax" vs. "user defined types and inconvenient function calls". > > > Here does lie the argument that I should be able define operators for user defined types, instead just TEXT and INTEGER and sets getting the special powers.. > > > Not to mention inlining via special support in the frontend. > (I realize a good backend could do the same). > > > interface int64; > > T = ARRAY[0..1] OF INTEGER. > > PROCEDURE +(a,b:T):T; > PROCEDURE *(a,b:T):T; > PROCEDURE /(a,b:T):T; > > > ? > > > etc... > > > Basically the "builtin" types are always more "convenient" than any user defined types. Only C++ as far as I know really attemps to solve that problem.. > > > > - Jay > > > ________________________________ >> From: hosking at cs.purdue.edu >> Date: Wed, 6 Jan 2010 02:11:53 -0500 >> To: hosking at cs.purdue.edu >> CC: m3devel at elegosoft.com; jay.krell at cornell.edu >> Subject: Re: [M3devel] A "radical" proposal: drop LONGINT >> >> >> >> PS Any type that *requires* 64-bit could be represented as: >> >> ARRAY [0..1] OF BITS 32 FOR [0..16_FFFFFFFF] >> >> or >> >> RECORD x, y: BITS 32 FOR [0..16_FFFFFFFF] END >> >> Is there ever a need to treat these as 64-bit integers? >> >> On 6 Jan 2010, at 02:06, Tony Hosking wrote: >> >> What do you need those 64-bit types for on 32-bit machines? On 32-bit machines INTEGER would still be 32-bit. >> >> On 6 Jan 2010, at 01:12, Jay K wrote: >> >> >> Can I still have: >> TYPE INT64 = BITS 64 FOR [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; >> or >> TYPE INT64 = [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; >> ? defined in an interface, not in the language? >> >> >> If so, probably ok. >> >> >> (And can I also somehow get: >> TYPE UINT32 = BITS 32 FOR [0..16_FFFFFFFF]; >> TYPE UINT64 = BITS 64 FOR [0..16_FFFFFFFFFFFFFFFF]; >> or >> TYPE UINT32 = [0..16_FFFFFFFF]; >> TYPE UINT64 = [0..16_FFFFFFFFFFFFFFFF]; >> ? >> ) >> >> >> Even on 32 bit machines? >> >> >> I know there is interface Word. >> >> >> And then, what is the difference between: >> >> >> on 32bit: >> INTEGER vs. [16_80000000..16_7FFFFFFF] >> CARDINAL vs. [0..16_7FFFFFFF] >> >> >> on 64bit: >> INTEGER vs. [16_8000000000000000..16_7FFFFFFFFFFFFFFF] >> CARDINAL vs. [0..16_7FFFFFFFFFFFFFFF] >> >> >> Any at all? >> Just that array sizes are cardinal? >> >> >> I don't know much about the language issues, but dealing with 64bit integers in 32bit Modula-3 ought to be about as easy and efficient as dealing with them in C and C++ I think. Hm..and why? Well..file sizes should be represented as 64bit integers, though they aren't yet..it seems to be a significant interface breaking change..though maybe range types aren't where LONGINT would be? I'll have to try that.. >> >> >> - Jay >> >> >> ________________________________ >> From: hosking at cs.purdue.edu >> Date: Tue, 5 Jan 2010 21:59:42 -0500 >> To: m3devel at elegosoft.com >> Subject: [M3devel] A "radical" proposal: drop LONGINT >> >> >> >> Now that Jay has carefully refactored all the C-dependent code, I'd like to pose the following question. What say we clean things up, revert to the original clean language definition, and eliminate LONGINT? It was only ever there for compatibility with C headers anyway, and these have all now been nicely abstracted away. The only remaining uses of LONGINT are in defining Modula-3 alternatives for C structs. These can be rewritten to something other than LONGINT. >> >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Wed Jan 6 18:49:46 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Wed, 06 Jan 2010 11:49:46 -0600 Subject: [M3devel] A "radical" proposal: drop LONGINT In-Reply-To: <1746EDCD-2BBE-4A4B-BACB-7EED5FEB29D2@cs.purdue.edu> References: , , , <84C08978-0083-4986-83D0-B3F255B5D526@cs.purdue.edu> <1746EDCD-2BBE-4A4B-BACB-7EED5FEB29D2@cs.purdue.edu> Message-ID: <4B44CD3A.9000501@lcwb.coop> Tony Hosking wrote: > But my question is what are the current use-cases for LONGINT? Do they > justify retaining it? > I want to code stuff that requires arithmetic in > 2^32 range, and be portable between 32- and 64-bit targets. Using a record with two INTEGERs on 32-bit machines and INTEGER on 64-bit machines would require a lot of code differences between the targets, and the differences can be pervasive. OTOH, using the record on all machines will not take advantage of native 64-bit arithmetic when available. Encapsulating the arithmetic in function calls also would add a lot of overhead, unless we had a compiler that would inline them, which, as I understand, we do not. It's also not as readable. I am a staunch opponent of adding user-definable operator overloading to get this readability advantage, because it interacts with all kinds of things and makes the language just absurdly overcomplicated. But LONGINT arithmetic is language-defined and highly constrained overloading, so the language complexity impact is much less. >>> >>> Antony Hosking | Associate Professor | Computer Science | Purdue >>> University >>> 305 N. University Street | West Lafayette | IN 47907 | USA >>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>> >>> > From rcolebur at SCIRES.COM Wed Jan 6 21:03:02 2010 From: rcolebur at SCIRES.COM (Randy Coleburn) Date: Wed, 6 Jan 2010 15:03:02 -0500 Subject: [M3devel] double double double double checking jmp_buf size/alignment In-Reply-To: References: Message-ID: Jay: Results on the following platforms are all identical: Windows 2000, Intel Pentium 3: 64 4 Windows XP, Intel Core Duo T2400: 64 4 Windows Vista, Intel Core2 Duo P9600: 64 4 Regards, Randy Coleburn From: jayk123 at hotmail.com [mailto:jayk123 at hotmail.com] On Behalf Of Jay K Sent: Wednesday, January 06, 2010 8:18 AM To: m3devel Subject: Re: [M3devel] double double double double checking jmp_buf size/alignment Was truncated!..edited slightly to avoid.. ________________________________ From: jay.krell at cornell.edu To: m3devel at elegosoft.com Subject: double double double double checking jmp_buf size/alignment Date: Wed, 6 Jan 2010 12:28:02 +0000 Getting this right is very important. Well, we can overstate but it is wasteful. So anyone with any time, please compile/run this and send the "platform" (uname -a) and the output, thanks. Or look at m3-libs/m3core/src/C/*/Csetjmp.i3 and m3-sys/m3middle/src/Target.m3 and see if all three agree. I have checked a bunch of systems myself but extra checking is good. If you have a system we do not yet or any longer support, those are ok too. (e.g. Alpha_*, ARM_*, MIPS_*, *_Irix, *_VMS, *_Tru64 etc.) #include #include #ifdef __GNUC__ #define ALIGN_OF(x) ((int)(sizeof(struct { char a; x b; }) - sizeof(x))) #else #define ALIGN_OF(x) ((int)__alignof(x)) int main() { printf("%d %d\n", (int)sizeof(jmp_buf), ALIGN_OF(jmp_buf)); return 0; } Thanks, - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jdp at polstra.com Wed Jan 6 22:06:00 2010 From: jdp at polstra.com (John Polstra) Date: Wed, 06 Jan 2010 13:06:00 -0800 Subject: [M3devel] A "radical" proposal: drop LONGINT In-Reply-To: References: Message-ID: <4B44FB38.3040704@polstra.com> File sizes and seek offsets (among other things) are 64 bits even on 32-bit machines, and files these days are often larger than 4GB. In many applications it is necessary to do arithmetic on such values. Also, the fact that Modula-3 traps integer overflows causes trouble when only 32 bits are used for file offsets. I had to put an ugly work-around into CVSup to avoid an integer overflow fault caused by more than 4GB being sent on a TCP connection. John Tony Hosking wrote: > What do you need those 64-bit types for on 32-bit machines? On 32-bit > machines INTEGER would still be 32-bit. > > On 6 Jan 2010, at 01:12, Jay K wrote: > >> >> Can I still have: >> TYPE INT64 = BITS 64 FOR [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; >> or >> TYPE INT64 = [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; >> ? defined in an interface, not in the language? >> >> >> If so, probably ok. >> >> >> (And can I also somehow get: >> TYPE UINT32 = BITS 32 FOR [0..16_FFFFFFFF]; >> TYPE UINT64 = BITS 64 FOR [0..16_FFFFFFFFFFFFFFFF]; >> or >> TYPE UINT32 = [0..16_FFFFFFFF]; >> TYPE UINT64 = [0..16_FFFFFFFFFFFFFFFF]; >> ? >> ) >> >> >> Even on 32 bit machines? >> >> >> I know there is interface Word. >> >> >> And then, what is the difference between: >> >> >> on 32bit: >> INTEGER vs. [16_80000000..16_7FFFFFFF] >> CARDINAL vs. [0..16_7FFFFFFF] >> >> >> on 64bit: >> INTEGER vs. [16_8000000000000000..16_7FFFFFFFFFFFFFFF] >> CARDINAL vs. [0..16_7FFFFFFFFFFFFFFF] >> >> >> Any at all? >> Just that array sizes are cardinal? >> >> >> I don't know much about the language issues, but dealing with 64bit >> integers in 32bit Modula-3 ought to be about as easy and efficient as >> dealing with them in C and C++ I think. Hm..and why? Well..file sizes >> should be represented as 64bit integers, though they aren't yet..it >> seems to be a significant interface breaking change..though maybe >> range types aren't where LONGINT would be? I'll have to try that.. >> >> >> - Jay >> >> >> ________________________________ >>> From: hosking at cs.purdue.edu >>> Date: Tue, 5 Jan 2010 21:59:42 -0500 >>> To: m3devel at elegosoft.com >>> Subject: [M3devel] A "radical" proposal: drop LONGINT >>> >>> >>> >>> Now that Jay has carefully refactored all the C-dependent code, I'd >>> like to pose the following question. What say we clean things up, >>> revert to the original clean language definition, and eliminate >>> LONGINT? It was only ever there for compatibility with C headers >>> anyway, and these have all now been nicely abstracted away. The only >>> remaining uses of LONGINT are in defining Modula-3 alternatives for C >>> structs. These can be rewritten to something other than LONGINT. >>> >>> >>> Antony Hosking | Associate Professor | Computer Science | Purdue >>> University >>> 305 N. University Street | West Lafayette | IN 47907 | USA >>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > From jay.krell at cornell.edu Thu Jan 7 04:35:55 2010 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Jan 2010 03:35:55 +0000 Subject: [M3devel] A "radical" proposal: drop LONGINT In-Reply-To: <4B44FB38.3040704@polstra.com> References: , , <4B44FB38.3040704@polstra.com> Message-ID: We still have a bug where merely browsing to a directory with a file > 4GB with the Trestle GUI raises an unhandled exception. Ideally LONGINT or [0..16_7FFFFFFFFFFFFFFF or higher] would be the type for file sizes everywhere. It is currently INTEGER and changing it to LONGINT breaks stuff. I'll try the subrange..maybe that'll compile... I think I proposed changing the type to "double" but nobody including me is super keen on that. Double does have an interesting property of offering far more range than a 32bit integer on all systems going way back... (53bits typically of precision within a 64bit double) - Jay > Date: Wed, 6 Jan 2010 13:06:00 -0800 > From: jdp at polstra.com > To: hosking at cs.purdue.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] A "radical" proposal: drop LONGINT > > File sizes and seek offsets (among other things) are 64 bits even on > 32-bit machines, and files these days are often larger than 4GB. In > many applications it is necessary to do arithmetic on such values. > Also, the fact that Modula-3 traps integer overflows causes trouble when > only 32 bits are used for file offsets. I had to put an ugly > work-around into CVSup to avoid an integer overflow fault caused by more > than 4GB being sent on a TCP connection. > > John > > Tony Hosking wrote: > > What do you need those 64-bit types for on 32-bit machines? On 32-bit > > machines INTEGER would still be 32-bit. > > > > On 6 Jan 2010, at 01:12, Jay K wrote: > > > >> > >> Can I still have: > >> TYPE INT64 = BITS 64 FOR [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; > >> or > >> TYPE INT64 = [16_8000000000000000..16_7FFFFFFFFFFFFFFF]; > >> ? defined in an interface, not in the language? > >> > >> > >> If so, probably ok. > >> > >> > >> (And can I also somehow get: > >> TYPE UINT32 = BITS 32 FOR [0..16_FFFFFFFF]; > >> TYPE UINT64 = BITS 64 FOR [0..16_FFFFFFFFFFFFFFFF]; > >> or > >> TYPE UINT32 = [0..16_FFFFFFFF]; > >> TYPE UINT64 = [0..16_FFFFFFFFFFFFFFFF]; > >> ? > >> ) > >> > >> > >> Even on 32 bit machines? > >> > >> > >> I know there is interface Word. > >> > >> > >> And then, what is the difference between: > >> > >> > >> on 32bit: > >> INTEGER vs. [16_80000000..16_7FFFFFFF] > >> CARDINAL vs. [0..16_7FFFFFFF] > >> > >> > >> on 64bit: > >> INTEGER vs. [16_8000000000000000..16_7FFFFFFFFFFFFFFF] > >> CARDINAL vs. [0..16_7FFFFFFFFFFFFFFF] > >> > >> > >> Any at all? > >> Just that array sizes are cardinal? > >> > >> > >> I don't know much about the language issues, but dealing with 64bit > >> integers in 32bit Modula-3 ought to be about as easy and efficient as > >> dealing with them in C and C++ I think. Hm..and why? Well..file sizes > >> should be represented as 64bit integers, though they aren't yet..it > >> seems to be a significant interface breaking change..though maybe > >> range types aren't where LONGINT would be? I'll have to try that.. > >> > >> > >> - Jay > >> > >> > >> ________________________________ > >>> From: hosking at cs.purdue.edu > >>> Date: Tue, 5 Jan 2010 21:59:42 -0500 > >>> To: m3devel at elegosoft.com > >>> Subject: [M3devel] A "radical" proposal: drop LONGINT > >>> > >>> > >>> > >>> Now that Jay has carefully refactored all the C-dependent code, I'd > >>> like to pose the following question. What say we clean things up, > >>> revert to the original clean language definition, and eliminate > >>> LONGINT? It was only ever there for compatibility with C headers > >>> anyway, and these have all now been nicely abstracted away. The only > >>> remaining uses of LONGINT are in defining Modula-3 alternatives for C > >>> structs. These can be rewritten to something other than LONGINT. > >>> > >>> > >>> Antony Hosking | Associate Professor | Computer Science | Purdue > >>> University > >>> 305 N. University Street | West Lafayette | IN 47907 | USA > >>> Office +1 765 494 6001 | Mobile +1 765 427 5484 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 7 07:59:31 2010 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Jan 2010 06:59:31 +0000 Subject: [M3devel] what to do about file sizes being 32bits? Message-ID: File.i3: Status = RECORD type: Type; modificationTime: Time.T; size: CARDINAL (* oops... *) END; What to do? [0.. higher than 7FFFFFFF] doesn't "just work". higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, which presumably has some relationship to turning it into a LONGINT, which causes users to fail to compile LONGINT doesn't "just work" causes users to fail to compile stale imports -> compiling ProcessPosixCommon.i3 stale imports -> compiling ProcessPosixCommon.m3 stale imports -> compiling ProcessPosix.m3 stale imports -> compiling FileRd.i3 missing version stamps -> compiling FileRd.m3 "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN "../src/rw/FileRd.m3", line 140: types are not assignable 2 errors encountered stale imports -> compiling FileWr.i3 missing version stamps -> compiling FileWr.m3 "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX 2 errors encountered st Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, hope the damage isn't too great outside the cm3 tree? Change it to LONGREAL so that it works immediately on NT386. Same issues as above, breaks existing users. Maybe relax the language some, so that e.g. a:INTEGER; b:LONGINT; b := a; just works, see if it helps make more code compile with the change? a := b is problematic of course, but what is wrong with b := a? - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 7 10:47:07 2010 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Jan 2010 09:47:07 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: Message-ID: I think I can fix everything in the cm3 tree if size is changed to LONGINT. Including Index(), Length(), Seek(). It involves *many* uses of VAL and ORD, and indeed, it would help if: INC(longint, integer) was legal, which seems perfectly ok. longint := integer ditto Most of the toplevel users will end up throwing in ORD, as they require files to fit in memory/addressspace. There is still the matter of this will break too much code out there. - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 06:59:31 +0000 Subject: [M3devel] what to do about file sizes being 32bits? File.i3: Status = RECORD type: Type; modificationTime: Time.T; size: CARDINAL (* oops... *) END; What to do? [0.. higher than 7FFFFFFF] doesn't "just work". higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, which presumably has some relationship to turning it into a LONGINT, which causes users to fail to compile LONGINT doesn't "just work" causes users to fail to compile stale imports -> compiling ProcessPosixCommon.i3 stale imports -> compiling ProcessPosixCommon.m3 stale imports -> compiling ProcessPosix.m3 stale imports -> compiling FileRd.i3 missing version stamps -> compiling FileRd.m3 "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN "../src/rw/FileRd.m3", line 140: types are not assignable 2 errors encountered stale imports -> compiling FileWr.i3 missing version stamps -> compiling FileWr.m3 "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX 2 errors encountered st Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, hope the damage isn't too great outside the cm3 tree? Change it to LONGREAL so that it works immediately on NT386. Same issues as above, breaks existing users. Maybe relax the language some, so that e.g. a:INTEGER; b:LONGINT; b := a; just works, see if it helps make more code compile with the change? a := b is problematic of course, but what is wrong with b := a? - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 7 12:22:37 2010 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Jan 2010 11:22:37 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , Message-ID: I'm working on this.. Attached is what I have so far. Posix needs work. Most code continues to not work for files >4GB on 32bit, but it is a start. It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. I'm not sure if the ToProc/FromProc stuff should use INTEGER/CARDINAL or LONGINT. This gets as far as: == package C:\dev2\cm3.2\m3-obliq\obliqrt == +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 -DCM3_VERSION_TEXT=d5.8.2 - DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ --- building in NT386 --- ignoring ..\src\m3overrides \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB m3cfe: (Error) failed to find source or AST for interface 'WordRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Word.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis suppressed due to import errors m3cfe: (Error) failed to find source or AST for interface 'LongRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Long.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic analysis suppresse d due to import errors "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic analysis suppr Which is probably some other problem? - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 09:47:07 +0000 Subject: Re: [M3devel] what to do about file sizes being 32bits? I think I can fix everything in the cm3 tree if size is changed to LONGINT. Including Index(), Length(), Seek(). It involves *many* uses of VAL and ORD, and indeed, it would help if: INC(longint, integer) was legal, which seems perfectly ok. longint := integer ditto Most of the toplevel users will end up throwing in ORD, as they require files to fit in memory/addressspace. There is still the matter of this will break too much code out there. - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 06:59:31 +0000 Subject: [M3devel] what to do about file sizes being 32bits? File.i3: Status = RECORD type: Type; modificationTime: Time.T; size: CARDINAL (* oops... *) END; What to do? [0.. higher than 7FFFFFFF] doesn't "just work". higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, which presumably has some relationship to turning it into a LONGINT, which causes users to fail to compile LONGINT doesn't "just work" causes users to fail to compile stale imports -> compiling ProcessPosixCommon.i3 stale imports -> compiling ProcessPosixCommon.m3 stale imports -> compiling ProcessPosix.m3 stale imports -> compiling FileRd.i3 missing version stamps -> compiling FileRd.m3 "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN "../src/rw/FileRd.m3", line 140: types are not assignable 2 errors encountered stale imports -> compiling FileWr.i3 missing version stamps -> compiling FileWr.m3 "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX 2 errors encountered st Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, hope the damage isn't too great outside the cm3 tree? Change it to LONGREAL so that it works immediately on NT386. Same issues as above, breaks existing users. Maybe relax the language some, so that e.g. a:INTEGER; b:LONGINT; b := a; just works, see if it helps make more code compile with the change? a := b is problematic of course, but what is wrong with b := a? - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 1.txt URL: From hendrik at topoi.pooq.com Thu Jan 7 14:11:17 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Thu, 7 Jan 2010 08:11:17 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: Message-ID: <20100107131117.GA22266@topoi.pooq.com> On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > > File.i3: > > > Status = RECORD > type: Type; > modificationTime: Time.T; > size: CARDINAL (* oops... *) > END; > > > What to do? > [0.. higher than 7FFFFFFF] doesn't "just work". > higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, > which presumably has some relationship to turning it into a LONGINT, which > causes users to fail to compile In any case, is the proper type for file offsets [0..7fffffffffffffff] or [0..ffffffffffffffff]? I suspect the latter. It might take some effort to make that legal in Modula 3. -- hendrik From wagner at elegosoft.com Thu Jan 7 14:52:10 2010 From: wagner at elegosoft.com (Olaf Wagner) Date: Thu, 07 Jan 2010 14:52:10 +0100 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100107131117.GA22266@topoi.pooq.com> References: <20100107131117.GA22266@topoi.pooq.com> Message-ID: <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> Quoting hendrik at topoi.pooq.com: > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: >> >> File.i3: >> >> >> Status = RECORD >> type: Type; >> modificationTime: Time.T; >> size: CARDINAL (* oops... *) >> END; >> >> >> What to do? >> [0.. higher than 7FFFFFFF] doesn't "just work". >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" >> on the end, >> which presumably has some relationship to turning it into a >> LONGINT, which >> causes users to fail to compile > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > or [0..ffffffffffffffff]? I suspect the latter. It might take some > effort to make that legal in Modula 3. Well, I don't think that should be any practical problem right now, shouldn't it? But 32 bit offsets have been overcome for years even on 32 bit systems, so I definitely think we should keep the LONGINT type and even try to incompatibly change the internal file length type (with due care and consideration of course). And please not for the still unfinished release, but for the next one. Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From hendrik at topoi.pooq.com Thu Jan 7 15:00:08 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Thu, 7 Jan 2010 09:00:08 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> References: <20100107131117.GA22266@topoi.pooq.com> <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> Message-ID: <20100107140008.GA25288@topoi.pooq.com> On Thu, Jan 07, 2010 at 02:52:10PM +0100, Olaf Wagner wrote: > Quoting hendrik at topoi.pooq.com: > > >In any case, is the proper type for file offsets [0..7fffffffffffffff] > >or [0..ffffffffffffffff]? I suspect the latter. It might take some > >effort to make that legal in Modula 3. > > Well, I don't think that should be any practical problem right now, > shouldn't it? Not just yet. But it will be, and I suspect Modula 3 will still be around then. -- hendrik From hosking at cs.purdue.edu Thu Jan 7 16:12:25 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 7 Jan 2010 10:12:25 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: Message-ID: <82B392A0-160D-4CD3-A36C-A64DFE7605ED@cs.purdue.edu> I've generally found it easy enough to fix clients so they use ORD(size) to convert LONGINT to INTEGER at the boundary between the library definitions and the application. This means they will get a run-time error if they access a file of size > LAST(INTEGER), so more pervasive changes will be needed to handle larger files. But that is the responsibility of the client code, not the library. The whole point of LONGINT was to support large file sizes. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On 7 Jan 2010, at 01:59, Jay K wrote: > File.i3: > > > Status = RECORD > type: Type; > modificationTime: Time.T; > size: CARDINAL (* oops... *) > END; > > > What to do? > [0.. higher than 7FFFFFFF] doesn't "just work". > higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, > which presumably has some relationship to turning it into a LONGINT, which > causes users to fail to compile > > > LONGINT doesn't "just work" > causes users to fail to compile > > > stale imports -> compiling ProcessPosixCommon.i3 > stale imports -> compiling ProcessPosixCommon.m3 > stale imports -> compiling ProcessPosix.m3 > stale imports -> compiling FileRd.i3 > missing version stamps -> compiling FileRd.m3 > "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN > "../src/rw/FileRd.m3", line 140: types are not assignable > 2 errors encountered > stale imports -> compiling FileWr.i3 > missing version stamps -> compiling FileWr.m3 > "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN > "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX > 2 errors encountered > st > > > Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, > hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGREAL so that it works immediately on NT386. > Same issues as above, breaks existing users. > > > Maybe relax the language some, so that e.g. > a:INTEGER; > b:LONGINT; > > b := a; > > just works, see if it helps make more code compile with the change? > > a := b is problematic of course, but what is wrong with b := a? > > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 7 16:13:58 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 7 Jan 2010 10:13:58 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: Message-ID: On 7 Jan 2010, at 04:47, Jay K wrote: > I think I can fix everything in the cm3 tree if size is changed to LONGINT. > Including Index(), Length(), Seek(). > It involves *many* uses of VAL and ORD, and indeed, it would help if: > > > INC(longint, integer) was legal, which seems perfectly ok. > longint := integer ditto I discourage both of these, just to emphasize that INTEGER and LONGINT are independent types. > Most of the toplevel users will end up throwing in ORD, as they > require files to fit in memory/addressspace. Right. > There is still the matter of this will break too much code out there. > > - Jay > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 06:59:31 +0000 > Subject: [M3devel] what to do about file sizes being 32bits? > > File.i3: > > > Status = RECORD > type: Type; > modificationTime: Time.T; > size: CARDINAL (* oops... *) > END; > > > What to do? > [0.. higher than 7FFFFFFF] doesn't "just work". > higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, > which presumably has some relationship to turning it into a LONGINT, which > causes users to fail to compile > > > LONGINT doesn't "just work" > causes users to fail to compile > > > stale imports -> compiling ProcessPosixCommon.i3 > stale imports -> compiling ProcessPosixCommon.m3 > stale imports -> compiling ProcessPosix.m3 > stale imports -> compiling FileRd.i3 > missing version stamps -> compiling FileRd.m3 > "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN > "../src/rw/FileRd.m3", line 140: types are not assignable > 2 errors encountered > stale imports -> compiling FileWr.i3 > missing version stamps -> compiling FileWr.m3 > "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN > "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX > 2 errors encountered > st > > > Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, > hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGREAL so that it works immediately on NT386. > Same issues as above, breaks existing users. > > > Maybe relax the language some, so that e.g. > a:INTEGER; > b:LONGINT; > > b := a; > > just works, see if it helps make more code compile with the change? > > a := b is problematic of course, but what is wrong with b := a? > > - Jay > From hosking at cs.purdue.edu Thu Jan 7 16:20:38 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 7 Jan 2010 10:20:38 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , Message-ID: <527D7354-97E5-47EB-A0FB-FDA7EE3D2B6A@cs.purdue.edu> On 7 Jan 2010, at 06:22, Jay K wrote: > I'm working on this.. > Attached is what I have so far. > Posix needs work. > Most code continues to not work for files >4GB on 32bit, but it is a start. > It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. > Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. Again, I discourage this as not in the spirit of the Modula-3 type system which abhors implicit casts. The problem below comes because I made WordRep and LongRep hidden interfaces. I've just reverted m3core/src/word/m3makefile so things will now work. > I'm not sure if the ToProc/FromProc stuff should use INTEGER/CARDINAL or LONGINT. > > This gets as far as: > > == package C:\dev2\cm3.2\m3-obliq\obliqrt == > > +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 -DCM3_VERSION_TEXT=d5.8.2 - > DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ > --- building in NT386 --- > > ignoring ..\src\m3overrides > > \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB > m3cfe: (Error) failed to find source or AST for interface 'WordRep' > "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Word.i3]": semanti > c analysis suppressed due to import errors > "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis suppressed due > to import errors > m3cfe: (Error) failed to find source or AST for interface 'LongRep' > "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Long.i3]": semanti > c analysis suppressed due to import errors > "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic analysis suppresse > d due to import errors > "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic analysis suppr > > > Which is probably some other problem? > > > - Jay > > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 09:47:07 +0000 > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > I think I can fix everything in the cm3 tree if size is changed to LONGINT. > Including Index(), Length(), Seek(). > It involves *many* uses of VAL and ORD, and indeed, it would help if: > > > INC(longint, integer) was legal, which seems perfectly ok. > longint := integer ditto > > > Most of the toplevel users will end up throwing in ORD, as they > require files to fit in memory/addressspace. > > > There is still the matter of this will break too much code out there. > > > - Jay > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 06:59:31 +0000 > Subject: [M3devel] what to do about file sizes being 32bits? > > File.i3: > > > Status = RECORD > type: Type; > modificationTime: Time.T; > size: CARDINAL (* oops... *) > END; > > > What to do? > [0.. higher than 7FFFFFFF] doesn't "just work". > higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, > which presumably has some relationship to turning it into a LONGINT, which > causes users to fail to compile > > > LONGINT doesn't "just work" > causes users to fail to compile > > > stale imports -> compiling ProcessPosixCommon.i3 > stale imports -> compiling ProcessPosixCommon.m3 > stale imports -> compiling ProcessPosix.m3 > stale imports -> compiling FileRd.i3 > missing version stamps -> compiling FileRd.m3 > "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN > "../src/rw/FileRd.m3", line 140: types are not assignable > 2 errors encountered > stale imports -> compiling FileWr.i3 > missing version stamps -> compiling FileWr.m3 > "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN > "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX > 2 errors encountered > st > > > Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, > hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGREAL so that it works immediately on NT386. > Same issues as above, breaks existing users. > > > Maybe relax the language some, so that e.g. > a:INTEGER; > b:LONGINT; > > b := a; > > just works, see if it helps make more code compile with the change? > > a := b is problematic of course, but what is wrong with b := a? > > - Jay > > <1.txt> -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 7 16:21:25 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 7 Jan 2010 10:21:25 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100107131117.GA22266@topoi.pooq.com> References: <20100107131117.GA22266@topoi.pooq.com> Message-ID: It will need to be a LONGINT type: [0L..16_7fffffffffffffffL] On 7 Jan 2010, at 08:11, hendrik at topoi.pooq.com wrote: > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: >> >> File.i3: >> >> >> Status = RECORD >> type: Type; >> modificationTime: Time.T; >> size: CARDINAL (* oops... *) >> END; >> >> >> What to do? >> [0.. higher than 7FFFFFFF] doesn't "just work". >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, >> which presumably has some relationship to turning it into a LONGINT, which >> causes users to fail to compile > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > or [0..ffffffffffffffff]? I suspect the latter. It might take some > effort to make that legal in Modula 3. > > -- hendrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 7 16:23:04 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 7 Jan 2010 10:23:04 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> References: <20100107131117.GA22266@topoi.pooq.com> <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> Message-ID: <2E21F50B-4710-4123-BB1F-FDF77CDB8C59@cs.purdue.edu> On 7 Jan 2010, at 08:52, Olaf Wagner wrote: > Well, I don't think that should be any practical problem right now, > shouldn't it? But 32 bit offsets have been overcome for years even > on 32 bit systems, so I definitely think we should keep the LONGINT > type and even try to incompatibly change the internal file length > type (with due care and consideration of course). I think I am now persuaded LONGINT should stay. But, I don't understand what "incompatibly change the internal file length type (with due care and consideration of course)" means? > > And please not for the still unfinished release, but for the next > one. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > From hendrik at topoi.pooq.com Thu Jan 7 17:46:20 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Thu, 7 Jan 2010 11:46:20 -0500 Subject: [M3devel] Integers Message-ID: <20100107164620.GA30061@topoi.pooq.com> I have some questions as to the constraints that need to be placed on integral types. These issues are fundamental to an understanding of the role of LONGINT, INTEGER, and CARDINAL, and what we should be doing about them. Is there a need for an integer type that can contain all the sizes of integers that can be handled by the language? I'll call it TOP just so I can talk about it easily. If it is necessary, is TOP only needed to make the language definition clean and concise? Conversely, is it necessary for TOP to be available to programmers? Is it necessary for TOP to be efficiently implemented, or implemented at all? Even if it is not available directly to programmers, are there language features that require it internally? Is it necessary that, for every two integer subranges I and J, there exist an integer range K such that both I and J are subranges of K? The most commonly used integral type is INTEGER. It seems to be the type used by programmers by default when they don't want to think of the specific range they will need. But is it necessary for the type called INTEGER to be TOP? Or, is there is no maximum implemented integral type, is it still necessary for INTEGER to be a maximal integral type? -- hendrik From jay.krell at cornell.edu Thu Jan 7 18:26:55 2010 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Jan 2010 17:26:55 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> References: , <20100107131117.GA22266@topoi.pooq.com>, <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> Message-ID: > Not in the current release Agreed. I think I'll have this done in the next few days, with the major caveat that it does break a lot of code. I'll fix the cm3 tree. The breakage is roughly: rd/wr users: before: a := Rd.Length(b); c := Rd.Index(b); Rd.Seek(b, d); after: a := ORD(Rd.Length(b)); c := ORD(Rd.Index(b)); Rd.Seek(b, VAL(d, LONGINT)); Though I think the last line should just work without change. rd/wr implementers: more substantial changes, but still similar, lots of ORD/VAL, and "L". One more compatible alternative might be to add LengthL, IndexL, SeekL? Maybe only break rd/wr implementers but not users? The reason I don't like that though is that it is even more of a no-op. Nobody will switch to the new functions. Similar to how "today" everybody will just ORD/VAL over the difference. To be clear though, the time for this change was 10 or 20 years ago. Now, 32bit systems are going away and with them this problem. (Amazingly, some 64bit systems still have 32bit time_t, like I think OpenBSD..) - Jay > Date: Thu, 7 Jan 2010 14:52:10 +0100 > From: wagner at elegosoft.com > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > Quoting hendrik at topoi.pooq.com: > > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > >> > >> File.i3: > >> > >> > >> Status = RECORD > >> type: Type; > >> modificationTime: Time.T; > >> size: CARDINAL (* oops... *) > >> END; > >> > >> > >> What to do? > >> [0.. higher than 7FFFFFFF] doesn't "just work". > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" > >> on the end, > >> which presumably has some relationship to turning it into a > >> LONGINT, which > >> causes users to fail to compile > > > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > > or [0..ffffffffffffffff]? I suspect the latter. It might take some > > effort to make that legal in Modula 3. > > Well, I don't think that should be any practical problem right now, > shouldn't it? But 32 bit offsets have been overcome for years even > on 32 bit systems, so I definitely think we should keep the LONGINT > type and even try to incompatibly change the internal file length > type (with due care and consideration of course). > > And please not for the still unfinished release, but for the next > one. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mika at async.async.caltech.edu Thu Jan 7 18:47:28 2010 From: mika at async.async.caltech.edu (Mika Nystrom) Date: Thu, 07 Jan 2010 09:47:28 -0800 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , <20100107131117.GA22266@topoi.pooq.com>, <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> Message-ID: <20100107174728.3A3D41A207D@async.async.caltech.edu> Jay K writes: >--_17b8aaee-1301-49c7-aaf8-b79f42004b70_ ... >One more compatible alternative might be to add LengthL=2C IndexL=2C SeekL? >Maybe only break rd/wr implementers but not users? > > >The reason I don't like that though is that it is even more of a no-op. >Nobody will switch to the new functions. >Similar to how "today" everybody will just ORD/VAL over the difference. Isn't this what the <*OBSOLETE*> pragma is for? Mika > > >To be clear though=2C the time for this change was 10 or 20 years ago. >Now=2C 32bit systems are going away and with them this problem. >(Amazingly=2C some 64bit systems still have 32bit time_t=2C like I think Op= >enBSD..) > > > - Jay > > >> Date: Thu=2C 7 Jan 2010 14:52:10 +0100 >> From: wagner at elegosoft.com >> To: m3devel at elegosoft.com >> Subject: Re: [M3devel] what to do about file sizes being 32bits? >>=20 >> Quoting hendrik at topoi.pooq.com: >>=20 >> > On Thu=2C Jan 07=2C 2010 at 06:59:31AM +0000=2C Jay K wrote: >> >> >> >> File.i3: >> >> >> >> >> >> Status =3D RECORD >> >> type: Type=3B >> >> modificationTime: Time.T=3B >> >> size: CARDINAL (* oops... *) >> >> END=3B >> >> >> >> >> >> What to do? >> >> [0.. higher than 7FFFFFFF] doesn't "just work". >> >> higher than 7FFFFFFFF is not legal on 32bit=2C unless you put "L" = >=20 >> >> on the end=2C >> >> which presumably has some relationship to turning it into a =20 >> >> LONGINT=2C which >> >> causes users to fail to compile >> > >> > In any case=2C is the proper type for file offsets [0..7fffffffffffffff= >] >> > or [0..ffffffffffffffff]? I suspect the latter. It might take some >> > effort to make that legal in Modula 3. >>=20 >> Well=2C I don't think that should be any practical problem right now=2C >> shouldn't it? But 32 bit offsets have been overcome for years even >> on 32 bit systems=2C so I definitely think we should keep the LONGINT >> type and even try to incompatibly change the internal file length >> type (with due care and consideration of course). >>=20 >> And please not for the still unfinished release=2C but for the next >> one. >>=20 >> Olaf >> --=20 >> Olaf Wagner -- elego Software Solutions GmbH >> Gustav-Meyer-Allee 25 / Geb=E4ude 12=2C 13355 Berlin=2C G= >ermany >> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86= > 95 >> http://www.elegosoft.com | Gesch=E4ftsf=FChrer: Olaf Wagner | Sitz: B= >erlin >> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214= >194 >>=20 > = > >--_17b8aaee-1301-49c7-aaf8-b79f42004b70_ >Content-Type: text/html; charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable > > > > > > >>=3B Not in the current release

Agreed.


I think I'll ha= >ve this done in the next few days=2C with the
major caveat that it does = >break a lot of code. I'll fix the cm3 tree.


The breakage is roug= >hly:


rd/wr users:
before:
 =3B a :=3D Rd.Length(b)=3B<= >br> =3B c :=3D Rd.Index(b)=3B
 =3B Rd.Seek(b=2C d)=3B
>

after:
 =3B a :=3D ORD(Rd.Length(b))=3B
> =3B c :=3D ORD(Rd.Index(b))=3B
> > =3B Rd.Seek(b=2C VAL(d=2C LONGINT))=3B
> >

Though I think the last line should just work without change.
r>
rd/wr implementers:
 =3Bmore substantial changes=2C but still = >similar=2C lots of ORD/VAL=2C and "L".


One more compatible alter= >native might be to add LengthL=2C IndexL=2C SeekL?
Maybe only break rd/w= >r implementers but not users?


The reason I don't like that thoug= >h is that it is even more of a no-op.
Nobody will switch to the new func= >tions.
Similar to how "today" everybody will just ORD/VAL over the diffe= >rence.


To be clear though=2C the time for this change was 10 or = >20 years ago.
Now=2C 32bit systems are going away and with them this pro= >blem.
(Amazingly=2C some 64bit systems still have 32bit time_t=2C like I= > think OpenBSD..)


 =3B- Jay


>=3B Date: Thu=2C 7= > Jan 2010 14:52:10 +0100
>=3B From: wagner at elegosoft.com
>=3B To:= > m3devel at elegosoft.com
>=3B Subject: Re: [M3devel] what to do about fi= >le sizes being 32bits?
>=3B
>=3B Quoting hendrik at topoi.pooq.com:= >
>=3B
>=3B >=3B On Thu=2C Jan 07=2C 2010 at 06:59:31AM +0000= >=2C Jay K wrote:
>=3B >=3B>=3B
>=3B >=3B>=3B File.i3:
= >>=3B >=3B>=3B
>=3B >=3B>=3B
>=3B >=3B>=3B Status = >=3D RECORD
>=3B >=3B>=3B type: Type=3B
>=3B >=3B>=3B = > modificationTime: Time.T=3B
>=3B >=3B>=3B size: CARDINAL (= >* oops... *)
>=3B >=3B>=3B END=3B
>=3B >=3B>=3B
>= >=3B >=3B>=3B
>=3B >=3B>=3B What to do?
>=3B >=3B>=3B = >[0.. higher than 7FFFFFFF] doesn't "just work".
>=3B >=3B>=3B h= >igher than 7FFFFFFFF is not legal on 32bit=2C unless you put "L"
>= >=3B >=3B>=3B on the end=2C
>=3B >=3B>=3B which presumably h= >as some relationship to turning it into a
>=3B >=3B>=3B LONGINT= >=2C which
>=3B >=3B>=3B causes users to fail to compile
>= >=3B >=3B
>=3B >=3B In any case=2C is the proper type for file offs= >ets [0..7fffffffffffffff]
>=3B >=3B or [0..ffffffffffffffff]? I sus= >pect the latter. It might take some
>=3B >=3B effort to make that l= >egal in Modula 3.
>=3B
>=3B Well=2C I don't think that should be= > any practical problem right now=2C
>=3B shouldn't it? But 32 bit offs= >ets have been overcome for years even
>=3B on 32 bit systems=2C so I d= >efinitely think we should keep the LONGINT
>=3B type and even try to i= >ncompatibly change the internal file length
>=3B type (with due care a= >nd consideration of course).
>=3B
>=3B And please not for the st= >ill unfinished release=2C but for the next
>=3B one.
>=3B
>= >=3B Olaf
>=3B --
>=3B Olaf Wagner -- elego Software Solutions Gm= >bH
>=3B Gustav-Meyer-Allee 25 / Geb=E4ude 12=2C 13355 = >Berlin=2C Germany
>=3B phone: +49 30 23 45 86 96 mobile: +49 177 2345= > 869 fax: +49 30 23 45 86 95
>=3B http://www.elegosoft.com | Gesc= >h=E4ftsf=FChrer: Olaf Wagner | Sitz: Berlin
>=3B Handelregister: Amtsg= >ericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194
>=3B
= > >= > >--_17b8aaee-1301-49c7-aaf8-b79f42004b70_-- From hosking at cs.purdue.edu Thu Jan 7 19:58:51 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 7 Jan 2010 13:58:51 -0500 Subject: [M3devel] Integers In-Reply-To: <20100107164620.GA30061@topoi.pooq.com> References: <20100107164620.GA30061@topoi.pooq.com> Message-ID: <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> I think your confusion relates to understanding how the language defines "base" types. You should understand that INTEGER and LONGINT have *different* base types. This indicates that they have inherently different representations, and indeed, operations on INTEGER and operations on LONGINT are inherently different. Every enumeration type similarly has a base type. If it's range is expressed over INTEGER values then its base type is INTEGER. If expressed over LONGINT then its base type is LONGINT. I don't think I understand the rest of your questions. On 7 Jan 2010, at 11:46, hendrik at topoi.pooq.com wrote: > I have some questions as to the constraints that need to be placed on > integral types. These issues are fundamental to an understanding of the > role of LONGINT, INTEGER, and CARDINAL, and what we should be doing > about them. > > Is there a need for an integer type that can contain all the sizes of > integers that can be handled by the language? I'll call it TOP just so > I can talk about it easily. > > If it is necessary, is TOP only needed to make the language definition > clean and concise? Conversely, is it necessary for TOP to be available > to programmers? Is it necessary for TOP to be efficiently implemented, > or implemented at all? > > Even if it is not available directly to programmers, are there language > features that require it internally? > > Is it necessary that, for every two integer subranges I and J, there > exist an integer range K such that both I and J are subranges of K? > > The most commonly used integral type is INTEGER. It seems to be the > type used by programmers by default when they don't want to think of > the specific range they will need. But is it necessary for the type > called INTEGER to be TOP? Or, is there is no maximum implemented > integral type, is it still necessary for INTEGER to be a maximal > integral type? > > -- hendrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 7 20:07:03 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 7 Jan 2010 14:07:03 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , <20100107131117.GA22266@topoi.pooq.com>, <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> Message-ID: Jay, I am *very* concerned that these changes are damaging the clarity of the language and its libraries in bad ways. What is so unreasonable about having the Modula-3 library interfaces place restrictions that continue to impose INTEGER file sizes. Just because the underlying OS allows files larger than that, if a program creates and manipulates files through the standard interfaces then they cannot ever see file sizes bigger than INTEGER. The interfaces support failure of Put operations on Wr.T that permit us to fail when exceeding the restricted file size. Please do not make these changes in the mainline trunk until further discussion. If you want to propose a set of changes I strongly suggest that you place them in a branch for evaluation by others! -- Tony On 7 Jan 2010, at 12:26, Jay K wrote: > > Not in the current release > > Agreed. > > > I think I'll have this done in the next few days, with the > major caveat that it does break a lot of code. I'll fix the cm3 tree. > > > The breakage is roughly: > > > rd/wr users: > before: > a := Rd.Length(b); > c := Rd.Index(b); > Rd.Seek(b, d); > > > after: > a := ORD(Rd.Length(b)); > c := ORD(Rd.Index(b)); > Rd.Seek(b, VAL(d, LONGINT)); > > > Though I think the last line should just work without change. > > > rd/wr implementers: > more substantial changes, but still similar, lots of ORD/VAL, and "L". > > > One more compatible alternative might be to add LengthL, IndexL, SeekL? > Maybe only break rd/wr implementers but not users? > > > The reason I don't like that though is that it is even more of a no-op. > Nobody will switch to the new functions. > Similar to how "today" everybody will just ORD/VAL over the difference. > > > To be clear though, the time for this change was 10 or 20 years ago. > Now, 32bit systems are going away and with them this problem. > (Amazingly, some 64bit systems still have 32bit time_t, like I think OpenBSD..) > > > - Jay > > > > Date: Thu, 7 Jan 2010 14:52:10 +0100 > > From: wagner at elegosoft.com > > To: m3devel at elegosoft.com > > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > > > Quoting hendrik at topoi.pooq.com: > > > > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > > >> > > >> File.i3: > > >> > > >> > > >> Status = RECORD > > >> type: Type; > > >> modificationTime: Time.T; > > >> size: CARDINAL (* oops... *) > > >> END; > > >> > > >> > > >> What to do? > > >> [0.. higher than 7FFFFFFF] doesn't "just work". > > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" > > >> on the end, > > >> which presumably has some relationship to turning it into a > > >> LONGINT, which > > >> causes users to fail to compile > > > > > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > > > or [0..ffffffffffffffff]? I suspect the latter. It might take some > > > effort to make that legal in Modula 3. > > > > Well, I don't think that should be any practical problem right now, > > shouldn't it? But 32 bit offsets have been overcome for years even > > on 32 bit systems, so I definitely think we should keep the LONGINT > > type and even try to incompatibly change the internal file length > > type (with due care and consideration of course). > > > > And please not for the still unfinished release, but for the next > > one. > > > > Olaf > > -- > > Olaf Wagner -- elego Software Solutions GmbH > > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 7 20:17:40 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 7 Jan 2010 14:17:40 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , <20100107131117.GA22266@topoi.pooq.com>, <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> Message-ID: <178ACFA7-7412-4406-B176-80E27976A202@cs.purdue.edu> I guess what I am really saying is that it does not seem unreasonable to me that Modula-3 (as a language) should be able to restrict the Rd.T and Wr.T instances to have a length that is always expressible as INTEGER. That was the point of my question about eliminating LONGINT. With the C interfaces abstracted, LONGINT would no longer be necessary. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On 7 Jan 2010, at 14:07, Tony Hosking wrote: > Jay, > > I am *very* concerned that these changes are damaging the clarity of the language and its libraries in bad ways. What is so unreasonable about having the Modula-3 library interfaces place restrictions that continue to impose INTEGER file sizes. Just because the underlying OS allows files larger than that, if a program creates and manipulates files through the standard interfaces then they cannot ever see file sizes bigger than INTEGER. The interfaces support failure of Put operations on Wr.T that permit us to fail when exceeding the restricted file size. Please do not make these changes in the mainline trunk until further discussion. If you want to propose a set of changes I strongly suggest that you place them in a branch for evaluation by others! > > -- Tony > > On 7 Jan 2010, at 12:26, Jay K wrote: > >> > Not in the current release >> >> Agreed. >> >> >> I think I'll have this done in the next few days, with the >> major caveat that it does break a lot of code. I'll fix the cm3 tree. >> >> >> The breakage is roughly: >> >> >> rd/wr users: >> before: >> a := Rd.Length(b); >> c := Rd.Index(b); >> Rd.Seek(b, d); >> >> >> after: >> a := ORD(Rd.Length(b)); >> c := ORD(Rd.Index(b)); >> Rd.Seek(b, VAL(d, LONGINT)); >> >> >> Though I think the last line should just work without change. >> >> >> rd/wr implementers: >> more substantial changes, but still similar, lots of ORD/VAL, and "L". >> >> >> One more compatible alternative might be to add LengthL, IndexL, SeekL? >> Maybe only break rd/wr implementers but not users? >> >> >> The reason I don't like that though is that it is even more of a no-op. >> Nobody will switch to the new functions. >> Similar to how "today" everybody will just ORD/VAL over the difference. >> >> >> To be clear though, the time for this change was 10 or 20 years ago. >> Now, 32bit systems are going away and with them this problem. >> (Amazingly, some 64bit systems still have 32bit time_t, like I think OpenBSD..) >> >> >> - Jay >> >> >> > Date: Thu, 7 Jan 2010 14:52:10 +0100 >> > From: wagner at elegosoft.com >> > To: m3devel at elegosoft.com >> > Subject: Re: [M3devel] what to do about file sizes being 32bits? >> > >> > Quoting hendrik at topoi.pooq.com: >> > >> > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: >> > >> >> > >> File.i3: >> > >> >> > >> >> > >> Status = RECORD >> > >> type: Type; >> > >> modificationTime: Time.T; >> > >> size: CARDINAL (* oops... *) >> > >> END; >> > >> >> > >> >> > >> What to do? >> > >> [0.. higher than 7FFFFFFF] doesn't "just work". >> > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" >> > >> on the end, >> > >> which presumably has some relationship to turning it into a >> > >> LONGINT, which >> > >> causes users to fail to compile >> > > >> > > In any case, is the proper type for file offsets [0..7fffffffffffffff] >> > > or [0..ffffffffffffffff]? I suspect the latter. It might take some >> > > effort to make that legal in Modula 3. >> > >> > Well, I don't think that should be any practical problem right now, >> > shouldn't it? But 32 bit offsets have been overcome for years even >> > on 32 bit systems, so I definitely think we should keep the LONGINT >> > type and even try to incompatibly change the internal file length >> > type (with due care and consideration of course). >> > >> > And please not for the still unfinished release, but for the next >> > one. >> > >> > Olaf >> > -- >> > Olaf Wagner -- elego Software Solutions GmbH >> > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany >> > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 >> > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin >> > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 7 21:31:31 2010 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Jan 2010 20:31:31 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <178ACFA7-7412-4406-B176-80E27976A202@cs.purdue.edu> References: , <20100107131117.GA22266@topoi.pooq.com>, <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> , <178ACFA7-7412-4406-B176-80E27976A202@cs.purdue.edu> Message-ID: Given that files are in fact larger than 4GB, why should we impose such a limit? Doesn't it make for a pretty lame system? Pretty much no existing 32bit C system for many years now any such limit and C started going past these limits around 15 years ago. It turns out changes I sent were pretty nearly done. I can now build all of "std" with LONGINT for file sizes. It's not just Rd/Wr, though that is most of it, it is also "File". - Jay Subject: Re: [M3devel] what to do about file sizes being 32bits? From: hosking at cs.purdue.edu Date: Thu, 7 Jan 2010 14:17:40 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: hosking at cs.purdue.edu I guess what I am really saying is that it does not seem unreasonable to me that Modula-3 (as a language) should be able to restrict the Rd.T and Wr.T instances to have a length that is always expressible as INTEGER. That was the point of my question about eliminating LONGINT. With the C interfaces abstracted, LONGINT would no longer be necessary. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 On 7 Jan 2010, at 14:07, Tony Hosking wrote: Jay, I am *very* concerned that these changes are damaging the clarity of the language and its libraries in bad ways. What is so unreasonable about having the Modula-3 library interfaces place restrictions that continue to impose INTEGER file sizes. Just because the underlying OS allows files larger than that, if a program creates and manipulates files through the standard interfaces then they cannot ever see file sizes bigger than INTEGER. The interfaces support failure of Put operations on Wr.T that permit us to fail when exceeding the restricted file size. Please do not make these changes in the mainline trunk until further discussion. If you want to propose a set of changes I strongly suggest that you place them in a branch for evaluation by others! -- Tony On 7 Jan 2010, at 12:26, Jay K wrote: > Not in the current release Agreed. I think I'll have this done in the next few days, with the major caveat that it does break a lot of code. I'll fix the cm3 tree. The breakage is roughly: rd/wr users: before: a := Rd.Length(b); c := Rd.Index(b); Rd.Seek(b, d); after: a := ORD(Rd.Length(b)); c := ORD(Rd.Index(b)); Rd.Seek(b, VAL(d, LONGINT)); Though I think the last line should just work without change. rd/wr implementers: more substantial changes, but still similar, lots of ORD/VAL, and "L". One more compatible alternative might be to add LengthL, IndexL, SeekL? Maybe only break rd/wr implementers but not users? The reason I don't like that though is that it is even more of a no-op. Nobody will switch to the new functions. Similar to how "today" everybody will just ORD/VAL over the difference. To be clear though, the time for this change was 10 or 20 years ago. Now, 32bit systems are going away and with them this problem. (Amazingly, some 64bit systems still have 32bit time_t, like I think OpenBSD..) - Jay > Date: Thu, 7 Jan 2010 14:52:10 +0100 > From: wagner at elegosoft.com > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > Quoting hendrik at topoi.pooq.com: > > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > >> > >> File.i3: > >> > >> > >> Status = RECORD > >> type: Type; > >> modificationTime: Time.T; > >> size: CARDINAL (* oops... *) > >> END; > >> > >> > >> What to do? > >> [0.. higher than 7FFFFFFF] doesn't "just work". > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" > >> on the end, > >> which presumably has some relationship to turning it into a > >> LONGINT, which > >> causes users to fail to compile > > > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > > or [0..ffffffffffffffff]? I suspect the latter. It might take some > > effort to make that legal in Modula 3. > > Well, I don't think that should be any practical problem right now, > shouldn't it? But 32 bit offsets have been overcome for years even > on 32 bit systems, so I definitely think we should keep the LONGINT > type and even try to incompatibly change the internal file length > type (with due care and consideration of course). > > And please not for the still unfinished release, but for the next > one. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 +49 30 23 45 86 96 mobile: +49 177 2345 869 +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Jan 7 21:33:22 2010 From: jay.krell at cornell.edu (Jay K) Date: Thu, 7 Jan 2010 20:33:22 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , <20100107131117.GA22266@topoi.pooq.com>, , <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com>, , Message-ID: I agree it isn't pretty but a big mistake was made many years ago, assuming file sizes are no larger than address spaces, and the current system might also not be so great (not allowing comparing a LONGINT to "0" or assigning it from an INTEGER). This seems to be about the best we can do. Can we maybe have a system where are really just subranges, and INTEGER is just a pre-declared one? Therefore INTEGER and LONGINT somewhat interchangable? Again, currently merely browsing to a directory with a large file raises an exception. - Jay From: hosking at cs.purdue.edu Date: Thu, 7 Jan 2010 14:07:03 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] what to do about file sizes being 32bits? Jay, I am *very* concerned that these changes are damaging the clarity of the language and its libraries in bad ways. What is so unreasonable about having the Modula-3 library interfaces place restrictions that continue to impose INTEGER file sizes. Just because the underlying OS allows files larger than that, if a program creates and manipulates files through the standard interfaces then they cannot ever see file sizes bigger than INTEGER. The interfaces support failure of Put operations on Wr.T that permit us to fail when exceeding the restricted file size. Please do not make these changes in the mainline trunk until further discussion. If you want to propose a set of changes I strongly suggest that you place them in a branch for evaluation by others! -- Tony On 7 Jan 2010, at 12:26, Jay K wrote: > Not in the current release Agreed. I think I'll have this done in the next few days, with the major caveat that it does break a lot of code. I'll fix the cm3 tree. The breakage is roughly: rd/wr users: before: a := Rd.Length(b); c := Rd.Index(b); Rd.Seek(b, d); after: a := ORD(Rd.Length(b)); c := ORD(Rd.Index(b)); Rd.Seek(b, VAL(d, LONGINT)); Though I think the last line should just work without change. rd/wr implementers: more substantial changes, but still similar, lots of ORD/VAL, and "L". One more compatible alternative might be to add LengthL, IndexL, SeekL? Maybe only break rd/wr implementers but not users? The reason I don't like that though is that it is even more of a no-op. Nobody will switch to the new functions. Similar to how "today" everybody will just ORD/VAL over the difference. To be clear though, the time for this change was 10 or 20 years ago. Now, 32bit systems are going away and with them this problem. (Amazingly, some 64bit systems still have 32bit time_t, like I think OpenBSD..) - Jay > Date: Thu, 7 Jan 2010 14:52:10 +0100 > From: wagner at elegosoft.com > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > Quoting hendrik at topoi.pooq.com: > > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > >> > >> File.i3: > >> > >> > >> Status = RECORD > >> type: Type; > >> modificationTime: Time.T; > >> size: CARDINAL (* oops... *) > >> END; > >> > >> > >> What to do? > >> [0.. higher than 7FFFFFFF] doesn't "just work". > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" > >> on the end, > >> which presumably has some relationship to turning it into a > >> LONGINT, which > >> causes users to fail to compile > > > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > > or [0..ffffffffffffffff]? I suspect the latter. It might take some > > effort to make that legal in Modula 3. > > Well, I don't think that should be any practical problem right now, > shouldn't it? But 32 bit offsets have been overcome for years even > on 32 bit systems, so I definitely think we should keep the LONGINT > type and even try to incompatibly change the internal file length > type (with due care and consideration of course). > > And please not for the still unfinished release, but for the next > one. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 7 22:33:41 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 7 Jan 2010 16:33:41 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , <20100107131117.GA22266@topoi.pooq.com>, <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> , <178ACFA7-7412-4406-B176-80E27976A202@cs.purdue.edu> Message-ID: <69B29C78-A38F-4068-BE4F-4073B284FF77@cs.purdue.edu> What do you mean by "files"? You are conflating OS "files" with Modula-3 Rd/Wr.T. They are not necessarily the same. Modula-3 is designed to be OS-independent. As you are already aware, some systems have only 32-bit addressable files. If we go the route you suggest then LONGINT will escape from a few isolated uses into the rest of the system. This seems overkill. With Rd/Wr.Length typed as INTEGER then on 64-bit systems you will have 64-bit addressable files. Elsewhere, 32-bit. I am really starting to think the addition of LONGINT was a big mistake. On 7 Jan 2010, at 15:31, Jay K wrote: > Given that files are in fact larger than 4GB, why should we impose such a limit? > Doesn't it make for a pretty lame system? > > Pretty much no existing 32bit C system for many years now any such limit and > C started going past these limits around 15 years ago. > > It turns out changes I sent were pretty nearly done. I can now build all of "std" > with LONGINT for file sizes. It's not just Rd/Wr, though that is most of it, it is also "File". > > > - Jay > > > Subject: Re: [M3devel] what to do about file sizes being 32bits? > From: hosking at cs.purdue.edu > Date: Thu, 7 Jan 2010 14:17:40 -0500 > CC: jay.krell at cornell.edu; m3devel at elegosoft.com > To: hosking at cs.purdue.edu > > I guess what I am really saying is that it does not seem unreasonable to me that Modula-3 (as a language) should be able to restrict the Rd.T and Wr.T instances to have a length that is always expressible as INTEGER. That was the point of my question about eliminating LONGINT. With the C interfaces abstracted, LONGINT would no longer be necessary. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 > > > > > On 7 Jan 2010, at 14:07, Tony Hosking wrote: > > Jay, > > I am *very* concerned that these changes are damaging the clarity of the language and its libraries in bad ways. What is so unreasonable about having the Modula-3 library interfaces place restrictions that continue to impose INTEGER file sizes. Just because the underlying OS allows files larger than that, if a program creates and manipulates files through the standard interfaces then they cannot ever see file sizes bigger than INTEGER. The interfaces support failure of Put operations on Wr.T that permit us to fail when exceeding the restricted file size. Please do not make these changes in the mainline trunk until further discussion. If you want to propose a set of changes I strongly suggest that you place them in a branch for evaluation by others! > > -- Tony > > On 7 Jan 2010, at 12:26, Jay K wrote: > > > Not in the current release > > Agreed. > > > I think I'll have this done in the next few days, with the > major caveat that it does break a lot of code. I'll fix the cm3 tree. > > > The breakage is roughly: > > > rd/wr users: > before: > a := Rd.Length(b); > c := Rd.Index(b); > Rd.Seek(b, d); > > > after: > a := ORD(Rd.Length(b)); > c := ORD(Rd.Index(b)); > Rd.Seek(b, VAL(d, LONGINT)); > > > Though I think the last line should just work without change. > > > rd/wr implementers: > more substantial changes, but still similar, lots of ORD/VAL, and "L". > > > One more compatible alternative might be to add LengthL, IndexL, SeekL? > Maybe only break rd/wr implementers but not users? > > > The reason I don't like that though is that it is even more of a no-op. > Nobody will switch to the new functions. > Similar to how "today" everybody will just ORD/VAL over the difference. > > > To be clear though, the time for this change was 10 or 20 years ago. > Now, 32bit systems are going away and with them this problem. > (Amazingly, some 64bit systems still have 32bit time_t, like I think OpenBSD..) > > > - Jay > > > > Date: Thu, 7 Jan 2010 14:52:10 +0100 > > From: wagner at elegosoft.com > > To: m3devel at elegosoft.com > > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > > > Quoting hendrik at topoi.pooq.com: > > > > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > > >> > > >> File.i3: > > >> > > >> > > >> Status = RECORD > > >> type: Type; > > >> modificationTime: Time.T; > > >> size: CARDINAL (* oops... *) > > >> END; > > >> > > >> > > >> What to do? > > >> [0.. higher than 7FFFFFFF] doesn't "just work". > > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" > > >> on the end, > > >> which presumably has some relationship to turning it into a > > >> LONGINT, which > > >> causes users to fail to compile > > > > > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > > > or [0..ffffffffffffffff]? I suspect the latter. It might take some > > > effort to make that legal in Modula 3. > > > > Well, I don't think that should be any practical problem right now, > > shouldn't it? But 32 bit offsets have been overcome for years even > > on 32 bit systems, so I definitely think we should keep the LONGINT > > type and even try to incompatibly change the internal file length > > type (with due care and consideration of course). > > > > And please not for the still unfinished release, but for the next > > one. > > > > Olaf > > -- > > Olaf Wagner -- elego Software Solutions GmbH > > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > > phone: +49 30 23 45 86 96 +49 30 23 45 86 96 mobile: +49 177 2345 869 +49 177 2345 869 fax: +49 30 23 45 86 95 > > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Jan 7 22:37:12 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 7 Jan 2010 16:37:12 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , <20100107131117.GA22266@topoi.pooq.com>, , <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com>, , Message-ID: On 7 Jan 2010, at 15:33, Jay K wrote: > I agree it isn't pretty but a big mistake was made many years ago, assuming file sizes are no larger than address spaces, > and the current system might also not be so great (not allowing comparing a LONGINT to "0" or assigning it from an INTEGER). > This seems to be about the best we can do. I actually think it is *much* cleaner to have Rd/Wr.T sizes no larger than address spaces. If someone really wants to use an OS-specific file size that is bigger than an address space then they can use the C interfaces, along with LONGINT. If they are working with Rd/Wr then they don't need to mess with the ugliness. > Can we maybe have a system where are really just subranges, and INTEGER is just a pre-declared one? > Therefore INTEGER and LONGINT somewhat interchangable? Again, this contradicts the design principles of the Modula-3 type system. > Again, currently merely browsing to a directory with a large file raises an exception. What code? Does it use C interfaces or the Modula-3 interfaces? > > > - Jay > > From: hosking at cs.purdue.edu > Date: Thu, 7 Jan 2010 14:07:03 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > Jay, > > I am *very* concerned that these changes are damaging the clarity of the language and its libraries in bad ways. What is so unreasonable about having the Modula-3 library interfaces place restrictions that continue to impose INTEGER file sizes. Just because the underlying OS allows files larger than that, if a program creates and manipulates files through the standard interfaces then they cannot ever see file sizes bigger than INTEGER. The interfaces support failure of Put operations on Wr.T that permit us to fail when exceeding the restricted file size. Please do not make these changes in the mainline trunk until further discussion. If you want to propose a set of changes I strongly suggest that you place them in a branch for evaluation by others! > > -- Tony > > On 7 Jan 2010, at 12:26, Jay K wrote: > > > Not in the current release > > Agreed. > > > I think I'll have this done in the next few days, with the > major caveat that it does break a lot of code. I'll fix the cm3 tree. > > > The breakage is roughly: > > > rd/wr users: > before: > a := Rd.Length(b); > c := Rd.Index(b); > Rd.Seek(b, d); > > > after: > a := ORD(Rd.Length(b)); > c := ORD(Rd.Index(b)); > Rd.Seek(b, VAL(d, LONGINT)); > > > Though I think the last line should just work without change. > > > rd/wr implementers: > more substantial changes, but still similar, lots of ORD/VAL, and "L". > > > One more compatible alternative might be to add LengthL, IndexL, SeekL? > Maybe only break rd/wr implementers but not users? > > > The reason I don't like that though is that it is even more of a no-op. > Nobody will switch to the new functions. > Similar to how "today" everybody will just ORD/VAL over the difference. > > > To be clear though, the time for this change was 10 or 20 years ago. > Now, 32bit systems are going away and with them this problem. > (Amazingly, some 64bit systems still have 32bit time_t, like I think OpenBSD..) > > > - Jay > > > > Date: Thu, 7 Jan 2010 14:52:10 +0100 > > From: wagner at elegosoft.com > > To: m3devel at elegosoft.com > > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > > > Quoting hendrik at topoi.pooq.com: > > > > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > > >> > > >> File.i3: > > >> > > >> > > >> Status = RECORD > > >> type: Type; > > >> modificationTime: Time.T; > > >> size: CARDINAL (* oops... *) > > >> END; > > >> > > >> > > >> What to do? > > >> [0.. higher than 7FFFFFFF] doesn't "just work". > > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" > > >> on the end, > > >> which presumably has some relationship to turning it into a > > >> LONGINT, which > > >> causes users to fail to compile > > > > > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > > > or [0..ffffffffffffffff]? I suspect the latter. It might take some > > > effort to make that legal in Modula 3. > > > > Well, I don't think that should be any practical problem right now, > > shouldn't it? But 32 bit offsets have been overcome for years even > > on 32 bit systems, so I definitely think we should keep the LONGINT > > type and even try to incompatibly change the internal file length > > type (with due care and consideration of course). > > > > And please not for the still unfinished release, but for the next > > one. > > > > Olaf > > -- > > Olaf Wagner -- elego Software Solutions GmbH > > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mika at async.async.caltech.edu Fri Jan 8 01:31:10 2010 From: mika at async.async.caltech.edu (Mika Nystrom) Date: Thu, 07 Jan 2010 16:31:10 -0800 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , <20100107131117.GA22266@topoi.pooq.com>, , <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com>, , Message-ID: <20100108003110.0BC1E1A207D@async.async.caltech.edu> Tony Hosking writes: > >--Apple-Mail-29--1022292864 >Content-Transfer-Encoding: quoted-printable >Content-Type: text/plain; > charset=iso-8859-1 > >On 7 Jan 2010, at 15:33, Jay K wrote: > >> I agree it isn't pretty but a big mistake was made many years ago, = >assuming file sizes are no larger than address spaces, >> and the current system might also not be so great (not allowing = >comparing a LONGINT to "0" or assigning it from an INTEGER). >> This seems to be about the best we can do. > >I actually think it is *much* cleaner to have Rd/Wr.T sizes no larger = >than address spaces. If someone really wants to use an OS-specific file = >size that is bigger than an address space then they can use the C = >interfaces, along with LONGINT. If they are working with Rd/Wr then = >they don't need to mess with the ugliness. Just to add my input to this discussion... I have programs that like to write huge log files (> 2GB), and with Wr.PutText this is a problem. But it's very easy to work around. Use the RdWrReset interface implemented as follows (not sure where I originally got this code from, Blair MacIntyre?): MODULE RdWrReset; IMPORT Rd AS R, Wr AS W; IMPORT RdClass, WrClass; <*NOWARN*>IMPORT UnsafeWr, UnsafeRd; (* Since we need to use the Mutex properties of Rd.T and Wr.T, we should actually import UnsafeWr and UnsafeRd. We need to add the following revelations, as the comment in UnsafeRd points out, if we want to include both the Unsafe* and *Class interfaces. *) REVEAL RdClass.Private <: MUTEX; REVEAL WrClass.Private <: MUTEX; PROCEDURE Rd (rd: R.T) = BEGIN LOCK rd DO DEC(rd.cur, rd.lo); DEC(rd.hi, rd.lo); rd.lo := 0; END; END Rd; PROCEDURE Wr (wr: W.T) = BEGIN LOCK wr DO DEC(wr.cur, wr.lo); DEC(wr.hi, wr.lo); wr.lo := 0; END; END Wr; BEGIN END RdWrReset. So far this has sufficed for me... Mika From jay.krell at cornell.edu Fri Jan 8 02:07:23 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 01:07:23 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <69B29C78-A38F-4068-BE4F-4073B284FF77@cs.purdue.edu> References: , , <20100107131117.GA22266@topoi.pooq.com>, , <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com>, , , , <178ACFA7-7412-4406-B176-80E27976A202@cs.purdue.edu>, , <69B29C78-A38F-4068-BE4F-4073B284FF77@cs.purdue.edu> Message-ID: > As you are already aware, some systems have only 32-bit addressable files. Really?! I don't think any system that we currently support or almost any that we would forseably lacks ability to use files larger than 4G. 4G has not been a large file size for quite a long time now. FreeBSD, NetBSD, NT, Linux, Solaris, AIX, Irix, VMS, HP-UX. 64bit file sizes in 32bit code. Maybe not MS-DOS, maybe not Win9x, but maybe esp. via remote file systems. > If we go the route you suggest then LONGINT will escape from a few isolated uses into the rest of the system. I can build "std" now. It does escape pretty far, but it is actually fairly contained. It would help a little of an INTEGER could be assigned to a LONGINT. Then the "porting" work for Rd/Wr users is just to add ORD on Index/Length calls. Currently they also need VAL(foo, LONGINT) also for Seek calls, which could be eliminated if.. > You are conflating OS "files" with Modula-3 Rd/Wr.T. Isn't that pretty natural? Aren't "file" one of the main things used with Rd/Wr? Besides that, if you consider "streams", going beyond 4G seems even more limiting. You know, I didn't change Read/Write/Get/whatever to use LONGINT. They require an in-memory buffer and therefore must use INTEGER or CARDINAL. I agree that dealing with such large files can be difficult, depending on the algorithms. But the "base" of the system shouldn't remove the ability for higher parts to do so. And resorting to C seems unnecessary. The operating system interfaces are essentially identical on Posix, as long you #define whatever. They vary at the ABI level for compatibility. Should I create a branch, or can we review the diffs and decide? - Jay From: hosking at cs.purdue.edu Date: Thu, 7 Jan 2010 16:33:41 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] what to do about file sizes being 32bits? What do you mean by "files"? You are conflating OS "files" with Modula-3 Rd/Wr.T. They are not necessarily the same. Modula-3 is designed to be OS-independent. As you are already aware, some systems have only 32-bit addressable files. If we go the route you suggest then LONGINT will escape from a few isolated uses into the rest of the system. This seems overkill. With Rd/Wr.Length typed as INTEGER then on 64-bit systems you will have 64-bit addressable files. Elsewhere, 32-bit. I am really starting to think the addition of LONGINT was a big mistake. On 7 Jan 2010, at 15:31, Jay K wrote: Given that files are in fact larger than 4GB, why should we impose such a limit? Doesn't it make for a pretty lame system? Pretty much no existing 32bit C system for many years now any such limit and C started going past these limits around 15 years ago. It turns out changes I sent were pretty nearly done. I can now build all of "std" with LONGINT for file sizes. It's not just Rd/Wr, though that is most of it, it is also "File". - Jay Subject: Re: [M3devel] what to do about file sizes being 32bits? From: hosking at cs.purdue.edu Date: Thu, 7 Jan 2010 14:17:40 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: hosking at cs.purdue.edu I guess what I am really saying is that it does not seem unreasonable to me that Modula-3 (as a language) should be able to restrict the Rd.T and Wr.T instances to have a length that is always expressible as INTEGER. That was the point of my question about eliminating LONGINT. With the C interfaces abstracted, LONGINT would no longer be necessary. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 On 7 Jan 2010, at 14:07, Tony Hosking wrote: Jay, I am *very* concerned that these changes are damaging the clarity of the language and its libraries in bad ways. What is so unreasonable about having the Modula-3 library interfaces place restrictions that continue to impose INTEGER file sizes. Just because the underlying OS allows files larger than that, if a program creates and manipulates files through the standard interfaces then they cannot ever see file sizes bigger than INTEGER. The interfaces support failure of Put operations on Wr.T that permit us to fail when exceeding the restricted file size. Please do not make these changes in the mainline trunk until further discussion. If you want to propose a set of changes I strongly suggest that you place them in a branch for evaluation by others! -- Tony On 7 Jan 2010, at 12:26, Jay K wrote: > Not in the current release Agreed. I think I'll have this done in the next few days, with the major caveat that it does break a lot of code. I'll fix the cm3 tree. The breakage is roughly: rd/wr users: before: a := Rd.Length(b); c := Rd.Index(b); Rd.Seek(b, d); after: a := ORD(Rd.Length(b)); c := ORD(Rd.Index(b)); Rd.Seek(b, VAL(d, LONGINT)); Though I think the last line should just work without change. rd/wr implementers: more substantial changes, but still similar, lots of ORD/VAL, and "L". One more compatible alternative might be to add LengthL, IndexL, SeekL? Maybe only break rd/wr implementers but not users? The reason I don't like that though is that it is even more of a no-op. Nobody will switch to the new functions. Similar to how "today" everybody will just ORD/VAL over the difference. To be clear though, the time for this change was 10 or 20 years ago. Now, 32bit systems are going away and with them this problem. (Amazingly, some 64bit systems still have 32bit time_t, like I think OpenBSD..) - Jay > Date: Thu, 7 Jan 2010 14:52:10 +0100 > From: wagner at elegosoft.com > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > Quoting hendrik at topoi.pooq.com: > > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > >> > >> File.i3: > >> > >> > >> Status = RECORD > >> type: Type; > >> modificationTime: Time.T; > >> size: CARDINAL (* oops... *) > >> END; > >> > >> > >> What to do? > >> [0.. higher than 7FFFFFFF] doesn't "just work". > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" > >> on the end, > >> which presumably has some relationship to turning it into a > >> LONGINT, which > >> causes users to fail to compile > > > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > > or [0..ffffffffffffffff]? I suspect the latter. It might take some > > effort to make that legal in Modula 3. > > Well, I don't think that should be any practical problem right now, > shouldn't it? But 32 bit offsets have been overcome for years even > on 32 bit systems, so I definitely think we should keep the LONGINT > type and even try to incompatibly change the internal file length > type (with due care and consideration of course). > > And please not for the still unfinished release, but for the next > one. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 mobile: +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 8 02:09:11 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 01:09:11 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <69B29C78-A38F-4068-BE4F-4073B284FF77@cs.purdue.edu> References: , , <20100107131117.GA22266@topoi.pooq.com>, , <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com>, , , , <178ACFA7-7412-4406-B176-80E27976A202@cs.purdue.edu>, , <69B29C78-A38F-4068-BE4F-4073B284FF77@cs.purdue.edu> Message-ID: To repeat myself, basically every system supports 64bit file sizes and they are easy to use from C. In my opinion, a "systems" language is something you can do "anything" in. Now, granted, the language isn't the issue here. But conflation of libraries and languages is common and not entirely invalid. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com Subject: RE: [M3devel] what to do about file sizes being 32bits? Date: Fri, 8 Jan 2010 01:07:23 +0000 > As you are already aware, some systems have only 32-bit addressable files. Really?! I don't think any system that we currently support or almost any that we would forseably lacks ability to use files larger than 4G. 4G has not been a large file size for quite a long time now. FreeBSD, NetBSD, NT, Linux, Solaris, AIX, Irix, VMS, HP-UX. 64bit file sizes in 32bit code. Maybe not MS-DOS, maybe not Win9x, but maybe esp. via remote file systems. > If we go the route you suggest then LONGINT will escape from a few isolated uses into the rest of the system. I can build "std" now. It does escape pretty far, but it is actually fairly contained. It would help a little of an INTEGER could be assigned to a LONGINT. Then the "porting" work for Rd/Wr users is just to add ORD on Index/Length calls. Currently they also need VAL(foo, LONGINT) also for Seek calls, which could be eliminated if.. > You are conflating OS "files" with Modula-3 Rd/Wr.T. Isn't that pretty natural? Aren't "file" one of the main things used with Rd/Wr? Besides that, if you consider "streams", going beyond 4G seems even more limiting. You know, I didn't change Read/Write/Get/whatever to use LONGINT. They require an in-memory buffer and therefore must use INTEGER or CARDINAL. I agree that dealing with such large files can be difficult, depending on the algorithms. But the "base" of the system shouldn't remove the ability for higher parts to do so. And resorting to C seems unnecessary. The operating system interfaces are essentially identical on Posix, as long you #define whatever. They vary at the ABI level for compatibility. Should I create a branch, or can we review the diffs and decide? - Jay From: hosking at cs.purdue.edu Date: Thu, 7 Jan 2010 16:33:41 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] what to do about file sizes being 32bits? What do you mean by "files"? You are conflating OS "files" with Modula-3 Rd/Wr.T. They are not necessarily the same. Modula-3 is designed to be OS-independent. As you are already aware, some systems have only 32-bit addressable files. If we go the route you suggest then LONGINT will escape from a few isolated uses into the rest of the system. This seems overkill. With Rd/Wr.Length typed as INTEGER then on 64-bit systems you will have 64-bit addressable files. Elsewhere, 32-bit. I am really starting to think the addition of LONGINT was a big mistake. On 7 Jan 2010, at 15:31, Jay K wrote: Given that files are in fact larger than 4GB, why should we impose such a limit? Doesn't it make for a pretty lame system? Pretty much no existing 32bit C system for many years now any such limit and C started going past these limits around 15 years ago. It turns out changes I sent were pretty nearly done. I can now build all of "std" with LONGINT for file sizes. It's not just Rd/Wr, though that is most of it, it is also "File". - Jay Subject: Re: [M3devel] what to do about file sizes being 32bits? From: hosking at cs.purdue.edu Date: Thu, 7 Jan 2010 14:17:40 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: hosking at cs.purdue.edu I guess what I am really saying is that it does not seem unreasonable to me that Modula-3 (as a language) should be able to restrict the Rd.T and Wr.T instances to have a length that is always expressible as INTEGER. That was the point of my question about eliminating LONGINT. With the C interfaces abstracted, LONGINT would no longer be necessary. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 On 7 Jan 2010, at 14:07, Tony Hosking wrote: Jay, I am *very* concerned that these changes are damaging the clarity of the language and its libraries in bad ways. What is so unreasonable about having the Modula-3 library interfaces place restrictions that continue to impose INTEGER file sizes. Just because the underlying OS allows files larger than that, if a program creates and manipulates files through the standard interfaces then they cannot ever see file sizes bigger than INTEGER. The interfaces support failure of Put operations on Wr.T that permit us to fail when exceeding the restricted file size. Please do not make these changes in the mainline trunk until further discussion. If you want to propose a set of changes I strongly suggest that you place them in a branch for evaluation by others! -- Tony On 7 Jan 2010, at 12:26, Jay K wrote: > Not in the current release Agreed. I think I'll have this done in the next few days, with the major caveat that it does break a lot of code. I'll fix the cm3 tree. The breakage is roughly: rd/wr users: before: a := Rd.Length(b); c := Rd.Index(b); Rd.Seek(b, d); after: a := ORD(Rd.Length(b)); c := ORD(Rd.Index(b)); Rd.Seek(b, VAL(d, LONGINT)); Though I think the last line should just work without change. rd/wr implementers: more substantial changes, but still similar, lots of ORD/VAL, and "L". One more compatible alternative might be to add LengthL, IndexL, SeekL? Maybe only break rd/wr implementers but not users? The reason I don't like that though is that it is even more of a no-op. Nobody will switch to the new functions. Similar to how "today" everybody will just ORD/VAL over the difference. To be clear though, the time for this change was 10 or 20 years ago. Now, 32bit systems are going away and with them this problem. (Amazingly, some 64bit systems still have 32bit time_t, like I think OpenBSD..) - Jay > Date: Thu, 7 Jan 2010 14:52:10 +0100 > From: wagner at elegosoft.com > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > Quoting hendrik at topoi.pooq.com: > > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > >> > >> File.i3: > >> > >> > >> Status = RECORD > >> type: Type; > >> modificationTime: Time.T; > >> size: CARDINAL (* oops... *) > >> END; > >> > >> > >> What to do? > >> [0.. higher than 7FFFFFFF] doesn't "just work". > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" > >> on the end, > >> which presumably has some relationship to turning it into a > >> LONGINT, which > >> causes users to fail to compile > > > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > > or [0..ffffffffffffffff]? I suspect the latter. It might take some > > effort to make that legal in Modula 3. > > Well, I don't think that should be any practical problem right now, > shouldn't it? But 32 bit offsets have been overcome for years even > on 32 bit systems, so I definitely think we should keep the LONGINT > type and even try to incompatibly change the internal file length > type (with due care and consideration of course). > > And please not for the still unfinished release, but for the next > one. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 mobile: +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 8 02:18:51 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 01:18:51 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <69B29C78-A38F-4068-BE4F-4073B284FF77@cs.purdue.edu> References: , , <20100107131117.GA22266@topoi.pooq.com>, , <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com>, , , , <178ACFA7-7412-4406-B176-80E27976A202@cs.purdue.edu>, , <69B29C78-A38F-4068-BE4F-4073B284FF77@cs.purdue.edu> Message-ID: [truncated] To repeat myself, basically every system supports 64bit file sizes and they are easy to use from C. In my opinion, a "systems" language is something you can do "anything" in. Now, granted, the language isn't the issue here. But conflation of libraries and languages is common and not entirely invalid. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com Subject: RE: [M3devel] what to do about file sizes being 32bits? Date: Fri, 8 Jan 2010 01:07:23 +0000 > As you are already aware, some systems have only 32-bit addressable files. Really?! I don't think any system that we currently support or almost any that we would forseably lacks ability to use files larger than 4G. 4G has not been a large file size for quite a long time now. FreeBSD, NetBSD, NT, Linux, Solaris, AIX, Irix, VMS, HP-UX. 64bit file sizes in 32bit code. Maybe not MS-DOS, maybe not Win9x, but maybe esp. via remote file systems. > If we go the route you suggest then LONGINT will escape from a few isolated uses into the rest of the system. I can build "std" now. It does escape pretty far, but it is actually fairly contained. It would help a little of an INTEGER could be assigned to a LONGINT. Then the "porting" work for Rd/Wr users is just to add ORD on Index/Length calls. Currently they also need VAL(foo, LONGINT) also for Seek calls, which could be eliminated if.. > You are conflating OS "files" with Modula-3 Rd/Wr.T. Isn't that pretty natural? Aren't "file" one of the main things used with Rd/Wr? Besides that, if you consider "streams", going beyond 4G seems even more limiting. You know, I didn't change Read/Write/Get/whatever to use LONGINT. They require an in-memory buffer and therefore must use INTEGER or CARDINAL. I agree that dealing with such large files can be difficult, depending on the algorithms. But the "base" of the system shouldn't remove the ability for higher parts to do so. And resorting to C seems unnecessary. The operating system interfaces are essentially identical on Posix, as long you #define whatever. They vary at the ABI level for compatibility. Should I create a branch, or can we review the diffs and decide? - Jay From: hosking at cs.purdue.edu Date: Thu, 7 Jan 2010 16:33:41 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] what to do about file sizes being 32bits? What do you mean by "files"? You are conflating OS "files" with Modula-3 Rd/Wr.T. They are not necessarily the same. Modula-3 is designed to be OS-independent. As you are already aware, some systems have only 32-bit addressable files. If we go the route you suggest then LONGINT will escape from a few isolated uses into the rest of the system. This seems overkill. With Rd/Wr.Length typed as INTEGER then on 64-bit systems you will have 64-bit addressable files. Elsewhere, 32-bit. I am really starting to think the addition of LONGINT was a big mistake. On 7 Jan 2010, at 15:31, Jay K wrote: Given that files are in fact larger than 4GB, why should we impose such a limit? Doesn't it make for a pretty lame system? Pretty much no existing 32bit C system for many years now any such limit and C started going past these limits around 15 years ago. It turns out changes I sent were pretty nearly done. I can now build all of "std" with LONGINT for file sizes. It's not just Rd/Wr, though that is most of it, it is also "File". - Jay Subject: Re: [M3devel] what to do about file sizes being 32bits? From: hosking at cs.purdue.edu Date: Thu, 7 Jan 2010 14:17:40 -0500 CC: jay.krell at cornell.edu; m3devel at elegosoft.com To: hosking at cs.purdue.edu I guess what I am really saying is that it does not seem unreasonable to me that Modula-3 (as a language) should be able to restrict the Rd.T and Wr.T instances to have a length that is always expressible as INTEGER. That was the point of my question about eliminating LONGINT. With the C interfaces abstracted, LONGINT would no longer be necessary. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 On 7 Jan 2010, at 14:07, Tony Hosking wrote: Jay, I am *very* concerned that these changes are damaging the clarity of the language and its libraries in bad ways. What is so unreasonable about having the Modula-3 library interfaces place restrictions that continue to impose INTEGER file sizes. Just because the underlying OS allows files larger than that, if a program creates and manipulates files through the standard interfaces then they cannot ever see file sizes bigger than INTEGER. The interfaces support failure of Put operations on Wr.T that permit us to fail when exceeding the restricted file size. Please do not make these changes in the mainline trunk until further discussion. If you want to propose a set of changes I strongly suggest that you place them in a branch for evaluation by others! -- Tony On 7 Jan 2010, at 12:26, Jay K wrote: > Not in the current release Agreed. I think I'll have this done in the next few days, with the major caveat that it does break a lot of code. I'll fix the cm3 tree. The breakage is roughly: rd/wr users: before: a := Rd.Length(b); c := Rd.Index(b); Rd.Seek(b, d); after: a := ORD(Rd.Length(b)); c := ORD(Rd.Index(b)); Rd.Seek(b, VAL(d, LONGINT)); Though I think the last line should just work without change. rd/wr implementers: more substantial changes, but still similar, lots of ORD/VAL, and "L". One more compatible alternative might be to add LengthL, IndexL, SeekL? Maybe only break rd/wr implementers but not users? The reason I don't like that though is that it is even more of a no-op. Nobody will switch to the new functions. Similar to how "today" everybody will just ORD/VAL over the difference. To be clear though, the time for this change was 10 or 20 years ago. Now, 32bit systems are going away and with them this problem. (Amazingly, some 64bit systems still have 32bit time_t, like I think OpenBSD..) - Jay > Date: Thu, 7 Jan 2010 14:52:10 +0100 > From: wagner at elegosoft.com > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > Quoting hendrik at topoi.pooq.com: > > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > >> > >> File.i3: > >> > >> > >> Status = RECORD > >> type: Type; > >> modificationTime: Time.T; > >> size: CARDINAL (* oops... *) > >> END; > >> > >> > >> What to do? > >> [0.. higher than 7FFFFFFF] doesn't "just work". > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" > >> on the end, > >> which presumably has some relationship to turning it into a > >> LONGINT, which > >> causes users to fail to compile > > > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > > or [0..ffffffffffffffff]? I suspect the latter. It might take some > > effort to make that legal in Modula 3. > > Well, I don't think that should be any practical problem right now, > shouldn't it? But 32 bit offsets have been overcome for years even > on 32 bit systems, so I definitely think we should keep the LONGINT > type and even try to incompatibly change the internal file length > type (with due care and consideration of course). > > And please not for the still unfinished release, but for the next > one. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 +49 30 23 45 86 96 mobile: +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Fri Jan 8 02:22:00 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Thu, 07 Jan 2010 19:22:00 -0600 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100107131117.GA22266@topoi.pooq.com> References: <20100107131117.GA22266@topoi.pooq.com> Message-ID: <4B4688B8.50701@lcwb.coop> Full-range unsigned integers are a language designer's headache, because there are conflicts no matter what you do. The Modula-3 approach is to use the operations in interface Word.i3 (and now Long.i3) on type INTEGER (not CARDINAL, which has only half the range). These apply unsigned interpretation to values of type INTEGER. hendrik at topoi.pooq.com wrote: > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: >> File.i3: >> >> >> Status = RECORD >> type: Type; >> modificationTime: Time.T; >> size: CARDINAL (* oops... *) >> END; >> >> >> What to do? >> [0.. higher than 7FFFFFFF] doesn't "just work". >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, >> which presumably has some relationship to turning it into a LONGINT, which >> causes users to fail to compile > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > or [0..ffffffffffffffff]? I suspect the latter. It might take some > effort to make that legal in Modula 3. > > -- hendrik > From jay.krell at cornell.edu Fri Jan 8 02:45:03 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 01:45:03 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <4B4688B8.50701@lcwb.coop> References: , <20100107131117.GA22266@topoi.pooq.com>, <4B4688B8.50701@lcwb.coop> Message-ID: I understand "full range" is a problem, because, something like, the set of operations isn't closed. I believe you need to define multiple types and/or multiple operations. You need an ability to trap/fail on overflow. You need an ability for silent wraparound on overflow. You need perhaps a way to add precision as needed. Slow. You need perhaps a way to specify arbitrarily high precision, and then, again, either trap/fail or silent wraparound. Basically, in my opinion, having just "INTEGER" and just "+" isn't nearly sufficient. Not having operator overloading makes pretty much any solution painful to use. We and C both have a compromise that covers most cases and when people really need higher fixed or arbitrary precision, they either give up the convenient "operator" syntax or use C++. As I understand, in C, unsigned integers are defined to "silently wraparound" and signed integers are implementation defined, could "trap" but in reality all implementations "silently wraparound". It is a point of unsafety though, beyond the more well known buffer overflows, leaks, etc. - Jay > Date: Thu, 7 Jan 2010 19:22:00 -0600 > From: rodney_bates at lcwb.coop > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > Full-range unsigned integers are a language designer's headache, because > there are conflicts no matter what you do. The Modula-3 approach is to > use the operations in interface Word.i3 (and now Long.i3) on type > INTEGER (not CARDINAL, which has only half the range). These apply > unsigned interpretation to values of type INTEGER. > > hendrik at topoi.pooq.com wrote: > > On Thu, Jan 07, 2010 at 06:59:31AM +0000, Jay K wrote: > >> File.i3: > >> > >> > >> Status = RECORD > >> type: Type; > >> modificationTime: Time.T; > >> size: CARDINAL (* oops... *) > >> END; > >> > >> > >> What to do? > >> [0.. higher than 7FFFFFFF] doesn't "just work". > >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, > >> which presumably has some relationship to turning it into a LONGINT, which > >> causes users to fail to compile > > > > In any case, is the proper type for file offsets [0..7fffffffffffffff] > > or [0..ffffffffffffffff]? I suspect the latter. It might take some > > effort to make that legal in Modula 3. > > > > -- hendrik > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Fri Jan 8 02:35:20 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Thu, 07 Jan 2010 19:35:20 -0600 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: Message-ID: <4B468BD8.4020106@lcwb.coop> I addressed all these details in my original LONGINT proposal, but it didn't get much attention at the time. That would have been October of 2007. I can't find the posts right now, because the link http://mailarchive.elegosoft.com/Zope/m3/m3devel is broken, and I have too many email account changes to be able to find it in my own inboxes. I proposed, and still do, that LONGINT be an ordinal type. This has the consequence, by preexisting rules, that INTEGER and LONGINT would be assignable to each other. This does not violate the preexisting language precedent, in fact, it is exactly like the preexisting rules for INTEGER and all its subtypes--they are assignable if the value is in the LHS type. This eliminates the necessity for the ORD and VAL conversions in most places, where there are mixtures of the types. Most places in the language require only assignability, not type equality. Exceptions include passing to a VAR formal and use in a type definition of a new type. A consequence of existing rules is that there would be, if necessary, runtime value checks. In many cases, including the examples we are discussing here, assigning a LONGINT to an INTEGER could well introduce a bug when a value is out of range, but this is no different from what happens when ORD/VAL are coded explicitly. On the other side of this argument, the necessity of coding ORD/VAL would point out statically, places where value range errors should be ruled out by the programmer. A conscientious programmer would then make an informed decision whether to just insert ORD/VAL, or whether it was necessary to change the INTEGER variable to LONGINT. But again, the already existing rules for subranges don't do this, so making INTEGER and LONGINT assignable would be consistent. Note that right now, the current implementation has a linguistic contradiction in that, if subranges of LONGINT are allowed, then LONGINT is an ordinal type, which implies LONGINT and INTEGER are mutually assignable. This could, of course be fixed in the language, but I would prefer making the two types assignable. Jay K wrote: > File.i3: > > > Status = RECORD > type: Type; > modificationTime: Time.T; > size: CARDINAL (* oops... *) > END; > > > What to do? > [0.. higher than 7FFFFFFF] doesn't "just work". > higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on > the end, > which presumably has some relationship to turning it into a LONGINT, > which > causes users to fail to compile > > > LONGINT doesn't "just work" > causes users to fail to compile > > > stale imports -> compiling ProcessPosixCommon.i3 > stale imports -> compiling ProcessPosixCommon.m3 > stale imports -> compiling ProcessPosix.m3 > stale imports -> compiling FileRd.i3 > missing version stamps -> compiling FileRd.m3 > "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN > "../src/rw/FileRd.m3", line 140: types are not assignable > 2 errors encountered > stale imports -> compiling FileWr.i3 > missing version stamps -> compiling FileWr.m3 > "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN > "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX > 2 errors encountered > st > > > Change it to LONGINT, fix all the callers, and hope the damage isn't too > great outside the cm3 tree? > > > Change it to LONGINT only for 32bit platforms, somehow author the cm3 > tree to work either way, > hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGREAL so that it works immediately on NT386. > Same issues as above, breaks existing users. > > > Maybe relax the language some, so that e.g. > a:INTEGER; > b:LONGINT; > > b := a; > > just works, see if it helps make more code compile with the change? > > a := b is problematic of course, but what is wrong with b := a? > > - Jay > From rodney_bates at lcwb.coop Fri Jan 8 02:37:39 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Thu, 07 Jan 2010 19:37:39 -0600 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <527D7354-97E5-47EB-A0FB-FDA7EE3D2B6A@cs.purdue.edu> References: , <527D7354-97E5-47EB-A0FB-FDA7EE3D2B6A@cs.purdue.edu> Message-ID: <4B468C63.9050404@lcwb.coop> Tony Hosking wrote: > On 7 Jan 2010, at 06:22, Jay K wrote: > >> I'm working on this.. >> Attached is what I have so far. >> Posix needs work. >> Most code continues to not work for files >4GB on 32bit, but it is a >> start. >> It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an >> INTEGER to a LONGINT, as all INTEGER values fit. >> Similarly I should be able to compare a LONGINT to 0 directly, instead >> of 0L. > > Again, I discourage this as not in the spirit of the Modula-3 type > system which abhors implicit casts. > Indeed, Modula-3 has no implicit casts at all. But it does have something that sometimes accomplishes the same result in a way that is far simpler to define and represents a higher level of abstraction, namely, the concept of assignability. A value, e.g. 10, can be in the value set of many types (INTEGER, many of its subranges, and now LONGINT and many if its subranges too). If so, it can in certain carefully specified cases, be assigned from one of these types to another, without any syntactically explicit notation required of the programmer. This represents the more abstract view that 10 is 10, as opposed to the usual view that 10 sitting in a byte is not the same as 10 in a word. Of course, at the machine level. they are not the same, but in Modula-3, that is only a representation matter that the compiler must take care of, not a high-level language matter that needs pages of rules to define. It took me years to fully understand the implications of replacing implicit type conversions by the assignability concept, but I now consider it one of Modula-3's great ideas, even if it is a small thing. From jay.krell at cornell.edu Fri Jan 8 03:01:23 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 02:01:23 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <4B468BD8.4020106@lcwb.coop> References: , <4B468BD8.4020106@lcwb.coop> Message-ID: I apologize for not paying close attention at the time. That seems to make sense to me now. There is at least an in-between version where INTEGER is assignable to LONGINT. In your proposal, the amount of source change required would be I think very very little. Some code would "just work" with large files, and some code would fail. - Jay > Date: Thu, 7 Jan 2010 19:35:20 -0600 > From: rodney_bates at lcwb.coop > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > > I addressed all these details in my original LONGINT proposal, but it > didn't get much attention at the time. That would have been October > of 2007. I can't find the posts right now, because the link > http://mailarchive.elegosoft.com/Zope/m3/m3devel is broken, and I have > too many email account changes to be able to find it in my own > inboxes. > > I proposed, and still do, that LONGINT be an ordinal type. This has > the consequence, by preexisting rules, that INTEGER and LONGINT would > be assignable to each other. This does not violate the preexisting > language precedent, in fact, it is exactly like the preexisting rules > for INTEGER and all its subtypes--they are assignable if the value is > in the LHS type. > > This eliminates the necessity for the ORD and VAL conversions in most > places, where there are mixtures of the types. Most places in the > language require only assignability, not type equality. Exceptions > include passing to a VAR formal and use in a type definition of a new > type. > > A consequence of existing rules is that there would be, if necessary, > runtime value checks. In many cases, including the examples we are > discussing here, assigning a LONGINT to an INTEGER could well > introduce a bug when a value is out of range, but this is no different > from what happens when ORD/VAL are coded explicitly. > > On the other side of this argument, the necessity of coding ORD/VAL > would point out statically, places where value range errors should be > ruled out by the programmer. A conscientious programmer would then > make an informed decision whether to just insert ORD/VAL, or whether > it was necessary to change the INTEGER variable to LONGINT. But > again, the already existing rules for subranges don't do this, so > making INTEGER and LONGINT assignable would be consistent. > > Note that right now, the current implementation has a linguistic > contradiction in that, if subranges of LONGINT are allowed, then > LONGINT is an ordinal type, which implies LONGINT and INTEGER are > mutually assignable. This could, of course be fixed in the language, > but I would prefer making the two types assignable. > > > > > Jay K wrote: > > File.i3: > > > > > > Status = RECORD > > type: Type; > > modificationTime: Time.T; > > size: CARDINAL (* oops... *) > > END; > > > > > > What to do? > > [0.. higher than 7FFFFFFF] doesn't "just work". > > higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on > > the end, > > which presumably has some relationship to turning it into a LONGINT, > > which > > causes users to fail to compile > > > > > > LONGINT doesn't "just work" > > causes users to fail to compile > > > > > > stale imports -> compiling ProcessPosixCommon.i3 > > stale imports -> compiling ProcessPosixCommon.m3 > > stale imports -> compiling ProcessPosix.m3 > > stale imports -> compiling FileRd.i3 > > missing version stamps -> compiling FileRd.m3 > > "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN > > "../src/rw/FileRd.m3", line 140: types are not assignable > > 2 errors encountered > > stale imports -> compiling FileWr.i3 > > missing version stamps -> compiling FileWr.m3 > > "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN > > "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX > > 2 errors encountered > > st > > > > > > Change it to LONGINT, fix all the callers, and hope the damage isn't too > > great outside the cm3 tree? > > > > > > Change it to LONGINT only for 32bit platforms, somehow author the cm3 > > tree to work either way, > > hope the damage isn't too great outside the cm3 tree? > > > > > > Change it to LONGREAL so that it works immediately on NT386. > > Same issues as above, breaks existing users. > > > > > > Maybe relax the language some, so that e.g. > > a:INTEGER; > > b:LONGINT; > > > > b := a; > > > > just works, see if it helps make more code compile with the change? > > > > a := b is problematic of course, but what is wrong with b := a? > > > > - Jay > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 8 02:58:33 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 01:58:33 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <4B468C63.9050404@lcwb.coop> References: , , , <527D7354-97E5-47EB-A0FB-FDA7EE3D2B6A@cs.purdue.edu>, <4B468C63.9050404@lcwb.coop> Message-ID: I don't believe currently "10" is assignable (or comparable) to LONGINT. You have to use 10L. I do believe any INTEGER or CARDINAL expression should be assignable to LONGINT, but I don't think it is implemented that way currently. And, then, I wonder if subranges are all we need, no LONGINT. But I don't understand the language well enough. - Jay > Date: Thu, 7 Jan 2010 19:37:39 -0600 > From: rodney_bates at lcwb.coop > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > > > Tony Hosking wrote: > > On 7 Jan 2010, at 06:22, Jay K wrote: > > > >> I'm working on this.. > >> Attached is what I have so far. > >> Posix needs work. > >> Most code continues to not work for files >4GB on 32bit, but it is a > >> start. > >> It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an > >> INTEGER to a LONGINT, as all INTEGER values fit. > >> Similarly I should be able to compare a LONGINT to 0 directly, instead > >> of 0L. > > > > Again, I discourage this as not in the spirit of the Modula-3 type > > system which abhors implicit casts. > > > Indeed, Modula-3 has no implicit casts at all. But it does have something > that sometimes accomplishes the same result in a way that is far simpler > to define and represents a higher level of abstraction, namely, the > concept of assignability. A value, e.g. 10, can be in the value set of > many types (INTEGER, many of its subranges, and now LONGINT and many if > its subranges too). If so, it can in certain carefully specified cases, > be assigned from one of these types to another, without any syntactically > explicit notation required of the programmer. > > This represents the more abstract view that 10 is 10, as opposed to the > usual view that 10 sitting in a byte is not the same as 10 in a word. > Of course, at the machine level. they are not the same, but in Modula-3, > that is only a representation matter that the compiler must take care of, > not a high-level language matter that needs pages of rules to define. > > It took me years to fully understand the implications of replacing implicit > type conversions by the assignability concept, but I now consider it one > of Modula-3's great ideas, even if it is a small thing. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 8 03:25:56 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 02:25:56 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , , , , , <527D7354-97E5-47EB-A0FB-FDA7EE3D2B6A@cs.purdue.edu>, , <4B468C63.9050404@lcwb.coop>, Message-ID: Here are some of the old messages. I haven't yet found a proposal. https://mail.elegosoft.com/pipermail/m3devel/2007-July/000323.html https://mail.elegosoft.com/pipermail/m3devel/2007-July/ https://mail.elegosoft.com/pipermail/m3devel/ You have to allow the exception for the certificate. - Jay From: jay.krell at cornell.edu To: rodney_bates at lcwb.coop; m3devel at elegosoft.com Date: Fri, 8 Jan 2010 01:58:33 +0000 Subject: Re: [M3devel] what to do about file sizes being 32bits? I don't believe currently "10" is assignable (or comparable) to LONGINT. You have to use 10L. I do believe any INTEGER or CARDINAL expression should be assignable to LONGINT, but I don't think it is implemented that way currently. And, then, I wonder if subranges are all we need, no LONGINT. But I don't understand the language well enough. - Jay > Date: Thu, 7 Jan 2010 19:37:39 -0600 > From: rodney_bates at lcwb.coop > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > > > Tony Hosking wrote: > > On 7 Jan 2010, at 06:22, Jay K wrote: > > > >> I'm working on this.. > >> Attached is what I have so far. > >> Posix needs work. > >> Most code continues to not work for files >4GB on 32bit, but it is a > >> start. > >> It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an > >> INTEGER to a LONGINT, as all INTEGER values fit. > >> Similarly I should be able to compare a LONGINT to 0 directly, instead > >> of 0L. > > > > Again, I discourage this as not in the spirit of the Modula-3 type > > system which abhors implicit casts. > > > Indeed, Modula-3 has no implicit casts at all. But it does have something > that sometimes accomplishes the same result in a way that is far simpler > to define and represents a higher level of abstraction, namely, the > concept of assignability. A value, e.g. 10, can be in the value set of > many types (INTEGER, many of its subranges, and now LONGINT and many if > its subranges too). If so, it can in certain carefully specified cases, > be assigned from one of these types to another, without any syntactically > explicit notation required of the programmer. > > This represents the more abstract view that 10 is 10, as opposed to the > usual view that 10 sitting in a byte is not the same as 10 in a word. > Of course, at the machine level. they are not the same, but in Modula-3, > that is only a representation matter that the compiler must take care of, > not a high-level language matter that needs pages of rules to define. > > It took me years to fully understand the implications of replacing implicit > type conversions by the assignability concept, but I now consider it one > of Modula-3's great ideas, even if it is a small thing. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 8 04:35:44 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 03:35:44 +0000 Subject: [M3devel] longint..revisited? Message-ID: I can't find Rodney's proposal but I think I understand a lot of it from today's mail. Can we revisit this? My understanding is that Rodney's proposal deems INTEGER assignable to LONGINT, and vice versa, and that assignments of LONGINT to INTEGER undergo runtime range checks, can raise exceptions. I assume it also follows that: LONGINT can be added/subtracted/modded to INTEGER, yielding LONGINT. INTEGER MOD LONGINT would range check the LONGINT. INC/DEC(LONGINT, INTEGER) would just work INC/DEC(INTEGER, LONGINT) would range check. The downside is that the chance for failure would be silently injected into various places. Another proposal would be that INTEGER is assignable to LONGINT, but not vice versa. I really don't see why not. LONGINT := INTEGER LONGINT + INTEGER => LONGINT LONGINT - INTEGER => LONGINT LONGINT * INTEGER => LONGINT LONGINT / INTEGER => LONGINT LONGINT MOD INTEGER => INTEGER (think about it) INC(LONGINT, INTEGER) DEC(LONGINT, INTEGER) all seem very reasonable. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hendrik at topoi.pooq.com Fri Jan 8 04:53:44 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Thu, 7 Jan 2010 22:53:44 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: <4B4688B8.50701@lcwb.coop> Message-ID: <20100108035343.GA9556@topoi.pooq.com> On Fri, Jan 08, 2010 at 01:45:03AM +0000, Jay K wrote: > > I understand "full range" is a problem, because, something like, > the set of operations isn't closed. What does this mean? What exactly do you mean by "full range"? And what do you mean by "closed"? > > I believe you need to define multiple types and/or > multiple operations. > > You need an ability to trap/fail on overflow. > > You need an ability for silent wraparound on overflow. > You need perhaps a way to add precision as needed. Slow. > You need perhaps a way to specify arbitrarily high precision, > and then, again, either trap/fail or silent wraparound. > > Basically, in my opinion, having just "INTEGER" and just "+" > isn't nearly sufficient. > > Not having operator overloading makes pretty much any solution painful to use. + is defined on integers and reals. If that's not an overload, why not have + defined on longint as well? > We and C both have a compromise that covers most cases and > when people really need higher fixed or arbitrary precision, they > either give up the convenient "operator" syntax or use C++. > > > As I understand, in C, unsigned integers are defined to "silently wraparound" The wraparound unsigned integers are extremely useful. The most common operations, +, *, and - have a clean, well-defined semantics as arithmetic modulo 2^n. It satisfies a lot of well-known algebraic identifies. Suppose you have an expression involving +, -, * and integers in 0..2^n - 1 and its correct result is in this 0..2^n - 1 range as well. If you evaluate it with nonwraparound arithmetic, you may get overflow. Nonetheless, using wraparound arithmetic under these conditions will still give the right answer. This makes wraparound integers useful for indexing strange arrays with, say, multiple subscripts in the rante 1000000000..1000000003. Intermediate results partway through subscript evaluations can overflow to their hearts' content, and you still get the right element in the end. > > and signed integers are implementation defined, could "trap" but in reality > all implementations "silently wraparound". > It is a point of unsafety though, beyond the more well known > buffer overflows, leaks, etc. > > - Jay > > > > Date: Thu, 7 Jan 2010 19:22:00 -0600 > > From: rodney_bates at lcwb.coop > > To: m3devel at elegosoft.com > > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > > > Full-range unsigned integers are a language designer's headache, because > > there are conflicts no matter what you do. The Modula-3 approach is to > > use the operations in interface Word.i3 (and now Long.i3) on type > > INTEGER (not CARDINAL, which has only half the range). These apply > > unsigned interpretation to values of type INTEGER. The problem with Word.i3 is that expressions involving these integers are so unreadable as to be seriously susceptible to error. -- hendrik From hendrik at topoi.pooq.com Fri Jan 8 05:03:33 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Thu, 7 Jan 2010 23:03:33 -0500 Subject: [M3devel] Integers In-Reply-To: <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> Message-ID: <20100108040333.GB9556@topoi.pooq.com> On Thu, Jan 07, 2010 at 01:58:51PM -0500, Tony Hosking wrote: > I think your confusion relates to understanding how the language > defines "base" types. > > You should understand that INTEGER and LONGINT have *different* base > types. This indicates that they have inherently different > representations, What's implicit in this statment is that all the subranges of INTEGER have inherently the same representation. Why is this inportant? Are there, for example, places in the language where you have a subrange but don't know what the subrange is? > and indeed, operations on INTEGER and operations on > LONGINT are inherently different. So in the language at present, there is no single type at the top of the integer type lattice (and it's not really a lattice). There are, however, two maximal types. Is this right? > > Every enumeration type similarly has a base type. If it's range is > expressed over INTEGER values then its base type is INTEGER. If > expressed over LONGINT then its base type is LONGINT. > > I don't think I understand the rest of your questions. Where in the language is it important that INTEGER and LONGINT be different base types? In other words, what advantages does this separation convey? -- hendrik > > On 7 Jan 2010, at 11:46, hendrik at topoi.pooq.com wrote: > > > I have some questions as to the constraints that need to be placed on > > integral types. These issues are fundamental to an understanding of the > > role of LONGINT, INTEGER, and CARDINAL, and what we should be doing > > about them. > > > > Is there a need for an integer type that can contain all the sizes of > > integers that can be handled by the language? I'll call it TOP just so > > I can talk about it easily. > > > > If it is necessary, is TOP only needed to make the language definition > > clean and concise? Conversely, is it necessary for TOP to be available > > to programmers? Is it necessary for TOP to be efficiently implemented, > > or implemented at all? > > > > Even if it is not available directly to programmers, are there language > > features that require it internally? > > > > Is it necessary that, for every two integer subranges I and J, there > > exist an integer range K such that both I and J are subranges of K? > > > > The most commonly used integral type is INTEGER. It seems to be the > > type used by programmers by default when they don't want to think of > > the specific range they will need. But is it necessary for the type > > called INTEGER to be TOP? Or, is there is no maximum implemented > > integral type, is it still necessary for INTEGER to be a maximal > > integral type? > > > > -- hendrik > From jay.krell at cornell.edu Fri Jan 8 07:07:08 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 06:07:08 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100108035343.GA9556@topoi.pooq.com> References: <4B4688B8.50701@lcwb.coop>, , <20100108035343.GA9556@topoi.pooq.com> Message-ID: I believe the right statement is: "fixed precision addition is not closed over addition/subtraction/multiplication" "closed" meaning the output set is not a subset of the output set. Let's just say our integers are 8 bits. The input range is -128..127. The output range however for addition is -256..254. The output range for subtraction is -255..255. (and if I'm slightly off, that's not the point) The output range for mulplication is..well nevermind, I know some of the rules: Adding two unsigned integers of n bits yields, worst case, n + 1 bits. Multiplying two unsigned integers of n bits yields, worst case, 2n bits. gotta run.. - Jay > Date: Thu, 7 Jan 2010 22:53:44 -0500 > From: hendrik at topoi.pooq.com > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > On Fri, Jan 08, 2010 at 01:45:03AM +0000, Jay K wrote: > > > > I understand "full range" is a problem, because, something like, > > the set of operations isn't closed. > > What does this mean? What exactly do you mean by "full range"? And > what do you mean by "closed"? > > > > > I believe you need to define multiple types and/or > > multiple operations. > > > > You need an ability to trap/fail on overflow. > > > > You need an ability for silent wraparound on overflow. > > You need perhaps a way to add precision as needed. Slow. > > You need perhaps a way to specify arbitrarily high precision, > > and then, again, either trap/fail or silent wraparound. > > > > Basically, in my opinion, having just "INTEGER" and just "+" > > isn't nearly sufficient. > > > > Not having operator overloading makes pretty much any solution painful to use. > > + is defined on integers and reals. If that's not an overload, why not > have + defined on longint as well? > > > We and C both have a compromise that covers most cases and > > when people really need higher fixed or arbitrary precision, they > > either give up the convenient "operator" syntax or use C++. > > > > > > As I understand, in C, unsigned integers are defined to "silently wraparound" > > The wraparound unsigned integers are extremely useful. The most common > operations, +, *, and - have a clean, well-defined semantics as > arithmetic modulo 2^n. It satisfies a lot of well-known algebraic > identifies. > > Suppose you have an expression involving +, -, * and integers in > 0..2^n - 1 and its correct result is in this 0..2^n - 1 range as well. > If you evaluate it with nonwraparound arithmetic, you may get overflow. > Nonetheless, using wraparound arithmetic under these conditions will > still give the right answer. > > This makes wraparound integers useful for indexing strange arrays with, > say, multiple subscripts in the rante 1000000000..1000000003. > Intermediate results partway through subscript evaluations can overflow > to their hearts' content, and you still get the right element in the > end. > > > > > and signed integers are implementation defined, could "trap" but in reality > > all implementations "silently wraparound". > > It is a point of unsafety though, beyond the more well known > > buffer overflows, leaks, etc. > > > > - Jay > > > > > > > Date: Thu, 7 Jan 2010 19:22:00 -0600 > > > From: rodney_bates at lcwb.coop > > > To: m3devel at elegosoft.com > > > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > > > > > Full-range unsigned integers are a language designer's headache, because > > > there are conflicts no matter what you do. The Modula-3 approach is to > > > use the operations in interface Word.i3 (and now Long.i3) on type > > > INTEGER (not CARDINAL, which has only half the range). These apply > > > unsigned interpretation to values of type INTEGER. > > The problem with Word.i3 is that expressions involving these integers > are so unreadable as to be seriously susceptible to error. > > -- hendrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 8 07:41:09 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 06:41:09 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100108035343.GA9556@topoi.pooq.com> References: <4B4688B8.50701@lcwb.coop>, , <20100108035343.GA9556@topoi.pooq.com> Message-ID: [truncated again, I have a knack for aiming near 80 columns and therefore getting the period right where the mail software truncates..] From: jay.krell at cornell.edu To: hendrik at topoi.pooq.com; m3devel at elegosoft.com Subject: RE: [M3devel] what to do about file sizes being 32bits? Date: Fri, 8 Jan 2010 06:07:08 +0000 I believe the right statement is: "fixed precision addition is not closed over addition/subtraction/multiplication" "closed" meaning the output set is not a subset of the output set. Let's just say our integers are 8 bits. The input range is -128..127. The output range however for addition is -256..254. The output range for subtraction is -255..255. (and if I'm slightly off, that's not the point) The output range for mulplication is..well nevermind, I know some of the rules: Adding two unsigned integers of n bits yields, worst case, n + 1 bits. Multiplying two unsigned integers of n bits yields, worst case, 2n bits. gotta run.. - Jay > Date: Thu, 7 Jan 2010 22:53:44 -0500 > From: hendrik at topoi.pooq.com > To: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > On Fri, Jan 08, 2010 at 01:45:03AM +0000, Jay K wrote: > > > > I understand "full range" is a problem, because, something like, > > the set of operations isn't closed. > > What does this mean? What exactly do you mean by "full range"? And > what do you mean by "closed"? > > > > > I believe you need to define multiple types and/or > > multiple operations. > > > > You need an ability to trap/fail on overflow. > > > > You need an ability for silent wraparound on overflow. > > You need perhaps a way to add precision as needed. Slow. > > You need perhaps a way to specify arbitrarily high precision, > > and then, again, either trap/fail or silent wraparound. > > > > Basically, in my opinion, having just "INTEGER" and just "+" > > isn't nearly sufficient. > > > > Not having operator overloading makes pretty much any solution painful to use. > > + is defined on integers and reals. If that's not an overload, why not > have + defined on longint as well? > > > We and C both have a compromise that covers most cases and > > when people really need higher fixed or arbitrary precision, they > > either give up the convenient "operator" syntax or use C++. > > > > > > As I understand, in C, unsigned integers are defined to "silently wraparound" > > The wraparound unsigned integers are extremely useful. The most common > operations, +, *, and - have a clean, well-defined semantics as > arithmetic modulo 2^n. It satisfies a lot of well-known algebraic > identifies. > > Suppose you have an expression involving +, -, * and integers in > 0..2^n - 1 and its correct result is in this 0..2^n - 1 range as well. > If you evaluate it with nonwraparound arithmetic, you may get overflow. > Nonetheless, using wraparound arithmetic under these conditions will > still give the right answer. > > This makes wraparound integers useful for indexing strange arrays with, > say, multiple subscripts in the rante 1000000000..1000000003. > Intermediate results partway through subscript evaluations can overflow > to their hearts' content, and you still get the right element in the > end. > > > > > and signed integers are implementation defined, could "trap" but in reality > > all implementations "silently wraparound". > > It is a point of unsafety though, beyond the more well known > > buffer overflows, leaks, etc. > > > > - Jay > > > > > > > Date: Thu, 7 Jan 2010 19:22:00 -0600 > > > From: rodney_bates at lcwb.coop > > > To: m3devel at elegosoft.com > > > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > > > > > Full-range unsigned integers are a language designer's headache, because > > > there are conflicts no matter what you do. The Modula-3 approach is to > > > use the operations in interface Word.i3 (and now Long.i3) on type > > > INTEGER (not CARDINAL, which has only half the range). These apply > > > unsigned interpretation to values of type INTEGER. > > The problem with Word.i3 is that expressions involving these integers > are so unreadable as to be seriously susceptible to error. > > -- hendrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 8 08:44:53 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 07:44:53 +0000 Subject: [M3devel] mixing INTEGER and LONGINT? Message-ID: This simple diff in the front end allows the "obvious" mixing of INTEGER and LONGINT without any need for ORD or VAL. LONGINT + INTEGER => LONGINT LONGINT - INTEGER => LONGINT LONGINT * INTEGER => LONGINT LONGINT DIV INTEGER => LONGINT INTEGER DIV LONGINT => LONGINT (subtle and I think incorrect, should be INTEGER) INTEGER MOD LONGINT => INTEGER (subtle but I believe correct) LONGINT MOD INTEGER => INTEGER (subtle but I believe correct) MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be INTEGER) MAX(INTEGER, LONGINT) => LONGINT LONGINT := INTEGER Other mixes are less obvious and would require runtime checks. I think the backend will just work but I haven't tried that yet. (Truth be told, I can only affectively edit files on NT...) Thoughts? - Jay Index: builtinOps/Dec.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Dec.m3,v retrieving revision 1.9 diff -u -r1.9 Dec.m3 --- builtinOps/Dec.m3 25 Sep 2009 02:42:10 -0000 1.9 +++ builtinOps/Dec.m3 8 Jan 2010 07:35:43 -0000 @@ -44,7 +44,7 @@ IF (NUMBER (ce.args^) > 1) THEN IF Type.IsSubtype (t, LInt.T) THEN t := Type.Base (Expr.TypeOf (ce.args[1])); - IF (t # LInt.T) THEN + IF t # LInt.T AND t # Int.T THEN Error.Txt (name, "second argument must be a LONGINT"); END; ELSE Index: builtinOps/Max.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Max.m3,v retrieving revision 1.3 diff -u -r1.3 Max.m3 --- builtinOps/Max.m3 18 Sep 2007 20:25:36 -0000 1.3 +++ builtinOps/Max.m3 8 Jan 2010 07:35:43 -0000 @@ -25,11 +25,14 @@ PROCEDURE DoCheck (name: TEXT; ce: CallExpr.T) = VAR ta, tb: Type.T; + resultType: Type.T := NIL; BEGIN ta := Type.Base (Expr.TypeOf (ce.args[0])); tb := Type.Base (Expr.TypeOf (ce.args[1])); - IF (NOT Type.IsEqual (ta, tb, NIL)) THEN + IF (ta = LInt.T AND tb = Int.T) OR (tb = LInt.T AND ta = Int.T) THEN + resultType := LInt.T; + ELSIF (NOT Type.IsEqual (ta, tb, NIL)) THEN Error.Txt (name, "incompatible argument types"); ELSIF (ta = Int.T) OR (ta = LInt.T) OR (Type.IsOrdinal (ta)) THEN (* ok *) @@ -39,7 +42,11 @@ Error.Txt (name, "wrong argument types"); ta := Int.T; END; - ce.type := ta; + IF resultType # NIL THEN + ce.type := resultType; + ELSE + ce.type := ta; + END; END DoCheck; PROCEDURE Compile (ce: CallExpr.T) = Index: exprs/AddExpr.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/AddExpr.m3,v retrieving revision 1.3 diff -u -r1.3 AddExpr.m3 --- exprs/AddExpr.m3 4 May 2008 11:03:45 -0000 1.3 +++ exprs/AddExpr.m3 8 Jan 2010 07:35:43 -0000 @@ -67,6 +67,7 @@ PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = VAR ta, tb, range: Type.T; + resultType: Type.T := NIL; BEGIN Expr.TypeCheck (p.a, cs); Expr.TypeCheck (p.b, cs); @@ -74,8 +75,9 @@ tb := Type.Base (Expr.TypeOf (p.b)); IF (ta = Int.T) AND (tb = Int.T) THEN p.class := Class.cINT; - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN - p.class := Class.cLINT + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN + p.class := Class.cLINT; + resultType := LInt.T; ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN p.class := Class.cREAL; ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN @@ -96,7 +98,11 @@ ELSE ta := Expr.BadOperands ("\'+\'", ta, tb); END; - p.type := ta; + IF resultType # NIL THEN + p.type := resultType; + ELSE + p.type := ta; + END; END Check; PROCEDURE Prep (p: P) = Index: exprs/DivExpr.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/DivExpr.m3,v retrieving revision 1.5 diff -u -r1.5 DivExpr.m3 --- exprs/DivExpr.m3 4 May 2008 11:03:46 -0000 1.5 +++ exprs/DivExpr.m3 8 Jan 2010 07:35:43 -0000 @@ -60,7 +60,7 @@ tb := Type.Base (Expr.TypeOf (p.b)); IF (ta = Int.T) AND (tb = Int.T) THEN p.type := Int.T; - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN p.type := LInt.T; ELSE p.type := Expr.BadOperands ("DIV", ta, tb); Index: exprs/ModExpr.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/ModExpr.m3,v retrieving revision 1.5 diff -u -r1.5 ModExpr.m3 --- exprs/ModExpr.m3 4 May 2008 11:03:46 -0000 1.5 +++ exprs/ModExpr.m3 8 Jan 2010 07:35:43 -0000 @@ -60,6 +60,7 @@ PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = VAR ta, tb: Type.T; + resultType: Type.T := NIL; BEGIN Expr.TypeCheck (p.a, cs); Expr.TypeCheck (p.b, cs); @@ -67,8 +68,18 @@ tb := Type.Base (Expr.TypeOf (p.b)); IF (ta = Int.T) AND (tb = Int.T) THEN p.class := Class.cINT; + ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN p.class := Class.cLINT; + + (* The result of MOD cannot be higher than either of its inputs. + * small divided by big is 0 remainder small + * big divided by small has a remainder of at most small + *) + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN + p.class := Class.cINT; + resultType := Int.T; + ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN p.class := Class.cREAL; ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN @@ -78,7 +89,11 @@ ELSE p.class := Class.cERR; ta := Int.T; ta := Expr.BadOperands ("MOD", ta, tb); END; - p.type := ta; + IF resultType # NIL THEN + p.type := resultType; + ELSE + p.type := ta; + END; END Check; PROCEDURE Prep (p: P) = Index: exprs/MultiplyExpr.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/MultiplyExpr.m3,v retrieving revision 1.3 diff -u -r1.3 MultiplyExpr.m3 --- exprs/MultiplyExpr.m3 4 May 2008 11:03:46 -0000 1.3 +++ exprs/MultiplyExpr.m3 8 Jan 2010 07:35:43 -0000 @@ -66,6 +66,7 @@ PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = VAR ta, tb, range: Type.T; + resultType: Type.T := NIL; BEGIN Expr.TypeCheck (p.a, cs); Expr.TypeCheck (p.b, cs); @@ -73,8 +74,9 @@ tb := Type.Base (Expr.TypeOf (p.b)); IF (tb = Int.T) AND (ta = Int.T) THEN p.class := cINT; - ELSIF (tb = LInt.T) AND (ta = LInt.T) THEN + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN p.class := cLINT; + resultType := LInt.T; ELSIF (tb = Reel.T) AND (ta = Reel.T) THEN p.class := cREAL; ELSIF (tb = LReel.T) AND (ta = LReel.T) THEN @@ -90,7 +92,11 @@ ta := Expr.BadOperands ("\'*\'", ta, tb); p.class := cINT; END; - p.type := ta; + IF resultType # NIL THEN + p.type := resultType; + ELSE + p.type := ta; + END; END Check; PROCEDURE Prep (p: P) = Index: exprs/SubtractExpr.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/SubtractExpr.m3,v retrieving revision 1.4 diff -u -r1.4 SubtractExpr.m3 --- exprs/SubtractExpr.m3 4 May 2008 11:03:46 -0000 1.4 +++ exprs/SubtractExpr.m3 8 Jan 2010 07:35:43 -0000 @@ -73,6 +73,7 @@ PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = VAR ta, tb, range: Type.T; + resultType: Type.T := NIL; BEGIN Expr.TypeCheck (p.a, cs); Expr.TypeCheck (p.b, cs); @@ -80,8 +81,9 @@ tb := Type.Base (Expr.TypeOf (p.b)); IF (ta = Int.T) AND (tb = Int.T) THEN p.class := Class.cINT; - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN p.class := Class.cLINT; + resultType := LInt.T; ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN p.class := Class.cREAL; ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN @@ -113,7 +115,11 @@ ta := Expr.BadOperands ("\'-\'", ta, tb); p.class := Class.cINT; END; - p.type := ta; + IF resultType # NIL THEN + p.type := resultType; + ELSE + p.type := ta; + END; END Check; PROCEDURE Prep (p: P) = Index: types/Type.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/Type.m3,v retrieving revision 1.8 diff -u -r1.8 Type.m3 --- types/Type.m3 4 May 2008 11:03:49 -0000 1.8 +++ types/Type.m3 8 Jan 2010 07:35:43 -0000 @@ -543,6 +543,10 @@ IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN RETURN TRUE; ELSIF IsOrdinal (a) THEN + (* INTEGER is assignable to LONGINT *) + IF a = LInt.T AND b = Int.T THEN + RETURN TRUE; + END; (* ordinal types: OK if there is a common supertype and they have at least one member in common. *) IF IsEqual (Base(a), Base(b), NIL) -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elegosoft.com Fri Jan 8 11:44:48 2010 From: wagner at elegosoft.com (Olaf Wagner) Date: Fri, 08 Jan 2010 11:44:48 +0100 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <2E21F50B-4710-4123-BB1F-FDF77CDB8C59@cs.purdue.edu> References: <20100107131117.GA22266@topoi.pooq.com> <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> <2E21F50B-4710-4123-BB1F-FDF77CDB8C59@cs.purdue.edu> Message-ID: <20100108114448.3fukoteb40og04og@mail.elegosoft.com> Quoting Tony Hosking : > On 7 Jan 2010, at 08:52, Olaf Wagner wrote: > >> Well, I don't think that should be any practical problem right now, > >> shouldn't it? But 32 bit offsets have been overcome for years even >> on 32 bit systems, so I definitely think we should keep the LONGINT >> type and even try to incompatibly change the internal file length >> type (with due care and consideration of course). > > I think I am now persuaded LONGINT should stay. But, I don't > understand what "incompatibly change the internal file length > type (with due care and consideration of course)" means? I only just got round to reading all those mails. I meant changing the file lengths and offsets in all our libraries, like Rd/Wr. Basically what Jay has started on right away ;-) I agree that this should be done in a feature branch though. Changes should be reviewed. Regression tests need to be run on all platforms. And of course we should all more or less agree that we want to do that. I think it has been a mistake that we haven't been able to support long file sizes in a consistent way throughout our code. Of course this problem will vanish in some years when everybody is using 64 bit platforms. But for embedded programming for example 32 bit processors may remain useful and in use much longer. I'm not sure if we should support assignability between INTEGER and LONGINT, as Rodney's original proposal did. Probably yes, but I must admit that I've been too little engaged in language theory for years now so that I cannot really oversee the impacts. Files with sizes larger than 4 GB get more and more common. Just think of DVD images for example. And I don't think that it will be really appreciated by users of M3 applications that they immediately crash just because one has opened a directory browser based on the distributed libraries :-) Just my opinion of course. I don't really understand why you are so drastically opposing LONGINT suddenly. Probably I haven't been able to follow some of the arguments. Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Fri Jan 8 12:13:58 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 11:13:58 +0000 Subject: [M3devel] latest longint file size diffs Message-ID: Attached is my latest work here. With the compiler changes (in the diff), I was able to elminate most uses of VAL(expr, LONGINT). There's something slightly off such that I had to add a very small number, like two. The compiler change is newer than earlier. For example you can now assign CARDINAL to LONGINT. I didn't do it, but you should also be able to add/subtract/etc. mixing CARDINAL and LONGINT. FOR statements also don't allow the level of mixing that they should. I'm hoping to get agreement soon just from the diffs but if necessary I'll look how to create a branch. My general worry about branches is developers just go off on their own in a branch and it's impossible to get anyone to look at it, they are busy enough with one branch, let alone multiple.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: dif8.txt URL: From wagner at elegosoft.com Fri Jan 8 12:32:24 2010 From: wagner at elegosoft.com (Olaf Wagner) Date: Fri, 08 Jan 2010 12:32:24 +0100 Subject: [M3devel] latest longint file size diffs In-Reply-To: References: Message-ID: <20100108123224.rryfffs1kw40k4sk@mail.elegosoft.com> Quoting Jay K : > Attached is my latest work here. > With the compiler changes (in the diff), I was able to > elminate most uses of VAL(expr, LONGINT). > There's something slightly off such that I had > to add a very small number, like two. > > The compiler change is newer than earlier. > > For example you can now assign CARDINAL to LONGINT. > > I didn't do it, but you should also be able to add/subtract/etc. > > mixing CARDINAL and LONGINT. > > FOR statements also don't allow the level of mixing > that they should. > > I'm hoping to get agreement soon just from the diffs > but if necessary I'll look how to create a branch. > > My general worry about branches is developers just > go off on their own in a branch and it's impossible to > get anyone to look at it, they are busy enough with one branch, > let alone multiple.. I think in this case it makes sense, as we need to run full regression tests on all target platforms IMO. You just should mark the start of the branch with cvs tag branch_feature_longint_offset_start then create the branch tag itself cvs tag -b branch_feature_longint_offset update your workspace to that branch cvs up -r branch_feature_longint_offset and finally commit the changes cvs commit This all assumes you've started on a fairly recent trunk and there are no conflicts. Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From hendrik at topoi.pooq.com Fri Jan 8 15:28:11 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 09:28:11 -0500 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: References: Message-ID: <20100108142811.GA14151@topoi.pooq.com> On Fri, Jan 08, 2010 at 07:44:53AM +0000, Jay K wrote: > > This simple diff in the front end allows the "obvious" mixing of INTEGER and LONGINT without any need for ORD or VAL. > > MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be INTEGER) No, it was correct. MIN( 5, -1000000000000000L) = -1000000000000000L So the result really needs to be LONGINT. From hosking at cs.purdue.edu Fri Jan 8 17:08:20 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 11:08:20 -0500 Subject: [M3devel] longint..revisited? In-Reply-To: References: Message-ID: <49C29A52-F861-4875-A6B0-B77758F08781@cs.purdue.edu> Again, this proposal raises serious problems regarding implicit coercions, against the design principals of the Modula-3 type system. On 7 Jan 2010, at 22:35, Jay K wrote: > I can't find Rodney's proposal but I think I understand > a lot of it from today's mail. > > > Can we revisit this? > > > My understanding is that Rodney's proposal > deems INTEGER assignable to LONGINT, > and vice versa, and that assignments of LONGINT > to INTEGER undergo runtime range checks, > can raise exceptions. > > > I assume it also follows that: > > > LONGINT can be added/subtracted/modded to INTEGER, > yielding LONGINT. > > > INTEGER MOD LONGINT would range check the LONGINT. > > > INC/DEC(LONGINT, INTEGER) would just work > > > INC/DEC(INTEGER, LONGINT) would range check. > > > The downside is that the chance for failure would be > silently injected into various places. > > > Another proposal would be that INTEGER is assignable to LONGINT, > but not vice versa. I really don't see why not. > > > LONGINT := INTEGER > LONGINT + INTEGER => LONGINT > LONGINT - INTEGER => LONGINT > LONGINT * INTEGER => LONGINT > LONGINT / INTEGER => LONGINT > LONGINT MOD INTEGER => INTEGER (think about it) > INC(LONGINT, INTEGER) > DEC(LONGINT, INTEGER) > > > all seem very reasonable. > > > - Jay > From hosking at cs.purdue.edu Fri Jan 8 17:17:07 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 11:17:07 -0500 Subject: [M3devel] Integers In-Reply-To: <20100108040333.GB9556@topoi.pooq.com> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> Message-ID: On 7 Jan 2010, at 23:03, hendrik at topoi.pooq.com wrote: > On Thu, Jan 07, 2010 at 01:58:51PM -0500, Tony Hosking wrote: >> I think your confusion relates to understanding how the language >> defines "base" types. >> >> You should understand that INTEGER and LONGINT have *different* base >> types. This indicates that they have inherently different >> representations, > > What's implicit in this statment is that all the subranges of INTEGER > have inherently the same representation. Why is this inportant? Are > there, for example, places in the language where you have a subrange > but don't know what the subrange is? A subrange always has a known base type. >> and indeed, operations on INTEGER and operations on >> LONGINT are inherently different. > > So in the language at present, there is no single type at the top of the > integer type lattice (and it's not really a lattice). There are, > however, two maximal types. Is this right? Correct. Here is the subtype rule for ordinals: For ordinal types T and U, we have T <: U if they have the same base type and every member of T is a member of U. That is, subtyping on ordinal types reflects the subset relation on the value sets. Currently, we have two possible base types for ordinals: INTEGER and LONGINT. They are distinct, unrelated types. >> Every enumeration type similarly has a base type. If it's range is >> expressed over INTEGER values then its base type is INTEGER. If >> expressed over LONGINT then its base type is LONGINT. >> >> I don't think I understand the rest of your questions. > > Where in the language is it important that INTEGER and LONGINT be > different base types? In other words, what advantages does this > separation convey? It conveys specific information about what specific machine values and operations implement them. They can (and usually do) require different code to operate on them. From a programmer's perspective, I know that every operation on INTEGER base values will involve *natural* integer arithmetic. For LONGINT I am much less sure, and may require even calling a library to perform the operation (if the machine doesn't naturally support LONGINT). > > -- hendrik >> >> On 7 Jan 2010, at 11:46, hendrik at topoi.pooq.com wrote: >> >>> I have some questions as to the constraints that need to be placed on >>> integral types. These issues are fundamental to an understanding of the >>> role of LONGINT, INTEGER, and CARDINAL, and what we should be doing >>> about them. >>> >>> Is there a need for an integer type that can contain all the sizes of >>> integers that can be handled by the language? I'll call it TOP just so >>> I can talk about it easily. >>> >>> If it is necessary, is TOP only needed to make the language definition >>> clean and concise? Conversely, is it necessary for TOP to be available >>> to programmers? Is it necessary for TOP to be efficiently implemented, >>> or implemented at all? >>> >>> Even if it is not available directly to programmers, are there language >>> features that require it internally? >>> >>> Is it necessary that, for every two integer subranges I and J, there >>> exist an integer range K such that both I and J are subranges of K? >>> >>> The most commonly used integral type is INTEGER. It seems to be the >>> type used by programmers by default when they don't want to think of >>> the specific range they will need. But is it necessary for the type >>> called INTEGER to be TOP? Or, is there is no maximum implemented >>> integral type, is it still necessary for INTEGER to be a maximal >>> integral type? >>> >>> -- hendrik >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Jan 8 17:26:07 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 11:26:07 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <4B468BD8.4020106@lcwb.coop> References: <4B468BD8.4020106@lcwb.coop> Message-ID: On 7 Jan 2010, at 20:35, Rodney M. Bates wrote: > I addressed all these details in my original LONGINT proposal, but it > didn't get much attention at the time. That would have been October > of 2007. I can't find the posts right now, because the link > http://mailarchive.elegosoft.com/Zope/m3/m3devel is broken, and I have > too many email account changes to be able to find it in my own > inboxes. > > I proposed, and still do, that LONGINT be an ordinal type. LONGINT *is* an ordinal type. It just has a different base type than INTEGER so it is not subtype-related. > This has > the consequence, by preexisting rules, that INTEGER and LONGINT would > be assignable to each other. This does not violate the preexisting > language precedent, in fact, it is exactly like the preexisting rules > for INTEGER and all its subtypes--they are assignable if the value is > in the LHS type. The question really is what should the top type be? We don't want to have all ordinal types base themselves on LONGINT because then they will all incur LONGINT operations (which may be more expensive than the "natural" INTEGER operations). > This eliminates the necessity for the ORD and VAL conversions in most > places, where there are mixtures of the types. Most places in the > language require only assignability, not type equality. Exceptions > include passing to a VAR formal and use in a type definition of a new > type. I really don't see how to accomodate this within the Modula-3 type system and its existing rules. Now, we could introduce an explicit rule that says INTEGER <: LONGINT. Then we can freely assign INTEGER values to LONGINT values. > A consequence of existing rules is that there would be, if necessary, > runtime value checks. In many cases, including the examples we are > discussing here, assigning a LONGINT to an INTEGER could well > introduce a bug when a value is out of range, but this is no different > from what happens when ORD/VAL are coded explicitly. Allowing assignment of LONGINT to INTEGER requires an implicit range check on assignment, but perhaps that is OK. > On the other side of this argument, the necessity of coding ORD/VAL > would point out statically, places where value range errors should be > ruled out by the programmer. A conscientious programmer would then > make an informed decision whether to just insert ORD/VAL, or whether > it was necessary to change the INTEGER variable to LONGINT. But > again, the already existing rules for subranges don't do this, so > making INTEGER and LONGINT assignable would be consistent. In this case I prefer the need for explicit conversion just so that programmers are made aware. > Note that right now, the current implementation has a linguistic > contradiction in that, if subranges of LONGINT are allowed, then > LONGINT is an ordinal type, which implies LONGINT and INTEGER are > mutually assignable. This could, of course be fixed in the language, > but I would prefer making the two types assignable. No, there is no contradiction in the current implementation. It treats subranges of LONGINT as having base type LONGINT. So they are unrelated to INTEGER based types. > > > > > Jay K wrote: >> File.i3: >> Status = RECORD >> type: Type; >> modificationTime: Time.T; >> size: CARDINAL (* oops... *) >> END; >> What to do? >> [0.. higher than 7FFFFFFF] doesn't "just work". >> higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, >> which presumably has some relationship to turning it into a LONGINT, which >> causes users to fail to compile >> LONGINT doesn't "just work" >> causes users to fail to compile >> stale imports -> compiling ProcessPosixCommon.i3 >> stale imports -> compiling ProcessPosixCommon.m3 >> stale imports -> compiling ProcessPosix.m3 >> stale imports -> compiling FileRd.i3 >> missing version stamps -> compiling FileRd.m3 >> "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN >> "../src/rw/FileRd.m3", line 140: types are not assignable >> 2 errors encountered >> stale imports -> compiling FileWr.i3 >> missing version stamps -> compiling FileWr.m3 >> "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN >> "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX >> 2 errors encountered >> st >> Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? >> Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, >> hope the damage isn't too great outside the cm3 tree? >> Change it to LONGREAL so that it works immediately on NT386. >> Same issues as above, breaks existing users. >> Maybe relax the language some, so that e.g. >> a:INTEGER; >> b:LONGINT; >> b := a; >> just works, see if it helps make more code compile with the change? >> a := b is problematic of course, but what is wrong with b := a? >> - Jay From hosking at cs.purdue.edu Fri Jan 8 17:27:36 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 11:27:36 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <4B468C63.9050404@lcwb.coop> References: , <527D7354-97E5-47EB-A0FB-FDA7EE3D2B6A@cs.purdue.edu> <4B468C63.9050404@lcwb.coop> Message-ID: Agreed. On 7 Jan 2010, at 20:37, Rodney M. Bates wrote: > > > Tony Hosking wrote: >> On 7 Jan 2010, at 06:22, Jay K wrote: >>> I'm working on this.. >>> Attached is what I have so far. >>> Posix needs work. >>> Most code continues to not work for files >4GB on 32bit, but it is a start. >>> It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. >>> Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. >> Again, I discourage this as not in the spirit of the Modula-3 type system which abhors implicit casts. > Indeed, Modula-3 has no implicit casts at all. But it does have something > that sometimes accomplishes the same result in a way that is far simpler > to define and represents a higher level of abstraction, namely, the > concept of assignability. A value, e.g. 10, can be in the value set of > many types (INTEGER, many of its subranges, and now LONGINT and many if > its subranges too). If so, it can in certain carefully specified cases, > be assigned from one of these types to another, without any syntactically > explicit notation required of the programmer. > > This represents the more abstract view that 10 is 10, as opposed to the > usual view that 10 sitting in a byte is not the same as 10 in a word. > Of course, at the machine level. they are not the same, but in Modula-3, > that is only a representation matter that the compiler must take care of, > not a high-level language matter that needs pages of rules to define. > > It took me years to fully understand the implications of replacing implicit > type conversions by the assignability concept, but I now consider it one > of Modula-3's great ideas, even if it is a small thing. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Jan 8 17:29:33 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 11:29:33 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100108035343.GA9556@topoi.pooq.com> References: <4B4688B8.50701@lcwb.coop> <20100108035343.GA9556@topoi.pooq.com> Message-ID: <303FF080-4129-4669-B264-151C32DE559F@cs.purdue.edu> On 7 Jan 2010, at 22:53, hendrik at topoi.pooq.com wrote: > + is defined on integers and reals. If that's not an overload, why not > have + defined on longint as well? We do have + defined on LONGINT. From hosking at cs.purdue.edu Fri Jan 8 17:36:18 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 11:36:18 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100108114448.3fukoteb40og04og@mail.elegosoft.com> References: <20100107131117.GA22266@topoi.pooq.com> <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> <2E21F50B-4710-4123-BB1F-FDF77CDB8C59@cs.purdue.edu> <20100108114448.3fukoteb40og04og@mail.elegosoft.com> Message-ID: <59DCA404-36FD-4EC0-B7AE-3FA59F3F6C4D@cs.purdue.edu> I am opposing LONGINT now (somewhat as a devil's advocate) because we introduced it simply to solve one very small problem: file sizes larger than INTEGER. Perhaps we would have been better off sticking with a double-INTEGER record with lo/hi fields to represent file sizes? Its introduction has added significant complication to the compiler, which I am frequently stumbling over (not to mention deep questions of typing in the language, as evidenced by the controversy over assignability between INTEGER and LONGINT). On 8 Jan 2010, at 05:44, Olaf Wagner wrote: > Quoting Tony Hosking : > >> On 7 Jan 2010, at 08:52, Olaf Wagner wrote: >> >>> Well, I don't think that should be any practical problem right now, >> >>> shouldn't it? But 32 bit offsets have been overcome for years even >>> on 32 bit systems, so I definitely think we should keep the LONGINT >>> type and even try to incompatibly change the internal file length >>> type (with due care and consideration of course). >> >> I think I am now persuaded LONGINT should stay. But, I don't understand what "incompatibly change the internal file length >> type (with due care and consideration of course)" means? > > I only just got round to reading all those mails. > > I meant changing the file lengths and offsets in all our libraries, > like Rd/Wr. Basically what Jay has started on right away ;-) > > I agree that this should be done in a feature branch though. > Changes should be reviewed. > Regression tests need to be run on all platforms. > > And of course we should all more or less agree that we want to do that. > I think it has been a mistake that we haven't been able to support > long file sizes in a consistent way throughout our code. Of course this > problem will vanish in some years when everybody is using 64 bit platforms. > But for embedded programming for example 32 bit processors may remain > useful and in use much longer. > > I'm not sure if we should support assignability between INTEGER and > LONGINT, as Rodney's original proposal did. Probably yes, but I must > admit that I've been too little engaged in language theory for years now > so that I cannot really oversee the impacts. > > Files with sizes larger than 4 GB get more and more common. Just think > of DVD images for example. And I don't think that it will be really > appreciated by users of M3 applications that they immediately crash > just because one has opened a directory browser based on the distributed > libraries :-) > > Just my opinion of course. I don't really understand why you are so > drastically opposing LONGINT suddenly. Probably I haven't been able to > follow some of the arguments. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > From hosking at cs.purdue.edu Fri Jan 8 18:00:01 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 12:00:01 -0500 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: References: Message-ID: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> Let's have a clean language proposal before thinking about implementing it... ;-) I continue to oppose mixing operations on both LONGINT and INTEGER. Just as one cannot mix REAL and LONGREAL. I may accept checked assignability between INTEGER and LONGINT (after all, the bits are the same, its just a matter of how many are significant -- unlike REAL/LONGREAL/EXTENDED). Looking further at the assignability rules: A type T is assignable to a type U if: ? T <: U, or ? U <: T and T is an array or a reference type other than ADDRESS (This restriction is lifted in unsafe modules.), or ? T and U are ordinal types with at least one member in common. This suggests that we don't really need to say that INTEGER <: LONGINT. We can simply rely on the third clause regarding their both being ordinal types with at least one member in common. Then assignment simply needs to test that the values are in range. On 8 Jan 2010, at 02:44, Jay K wrote: > This simple diff in the front end allows the "obvious" mixing of INTEGER and LONGINT without any need for ORD or VAL. > > LONGINT + INTEGER => LONGINT > LONGINT - INTEGER => LONGINT > LONGINT * INTEGER => LONGINT > LONGINT DIV INTEGER => LONGINT > INTEGER DIV LONGINT => LONGINT (subtle and I think incorrect, should be INTEGER) > INTEGER MOD LONGINT => INTEGER (subtle but I believe correct) > LONGINT MOD INTEGER => INTEGER (subtle but I believe correct) > MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be INTEGER) > MAX(INTEGER, LONGINT) => LONGINT > LONGINT := INTEGER > > Other mixes are less obvious and would require runtime checks. > > I think the backend will just work but I haven't tried that yet. > (Truth be told, I can only affectively edit files on NT...) > > Thoughts? > > - Jay > > Index: builtinOps/Dec.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Dec.m3,v > retrieving revision 1.9 > diff -u -r1.9 Dec.m3 > --- builtinOps/Dec.m3 25 Sep 2009 02:42:10 -0000 1.9 > +++ builtinOps/Dec.m3 8 Jan 2010 07:35:43 -0000 > @@ -44,7 +44,7 @@ > IF (NUMBER (ce.args^) > 1) THEN > IF Type.IsSubtype (t, LInt.T) THEN > t := Type.Base (Expr.TypeOf (ce.args[1])); > - IF (t # LInt.T) THEN > + IF t # LInt.T AND t # Int.T THEN > Error.Txt (name, "second argument must be a LONGINT"); > END; > ELSE > Index: builtinOps/Max.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Max.m3,v > retrieving revision 1.3 > diff -u -r1.3 Max.m3 > --- builtinOps/Max.m3 18 Sep 2007 20:25:36 -0000 1.3 > +++ builtinOps/Max.m3 8 Jan 2010 07:35:43 -0000 > @@ -25,11 +25,14 @@ > > PROCEDURE DoCheck (name: TEXT; ce: CallExpr.T) = > VAR ta, tb: Type.T; > + resultType: Type.T := NIL; > BEGIN > ta := Type.Base (Expr.TypeOf (ce.args[0])); > tb := Type.Base (Expr.TypeOf (ce.args[1])); > > - IF (NOT Type.IsEqual (ta, tb, NIL)) THEN > + IF (ta = LInt.T AND tb = Int.T) OR (tb = LInt.T AND ta = Int.T) THEN > + resultType := LInt.T; > + ELSIF (NOT Type.IsEqual (ta, tb, NIL)) THEN > Error.Txt (name, "incompatible argument types"); > ELSIF (ta = Int.T) OR (ta = LInt.T) OR (Type.IsOrdinal (ta)) THEN > (* ok *) > @@ -39,7 +42,11 @@ > Error.Txt (name, "wrong argument types"); > ta := Int.T; > END; > - ce.type := ta; > + IF resultType # NIL THEN > + ce.type := resultType; > + ELSE > + ce.type := ta; > + END; > END DoCheck; > > PROCEDURE Compile (ce: CallExpr.T) = > Index: exprs/AddExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/AddExpr.m3,v > retrieving revision 1.3 > diff -u -r1.3 AddExpr.m3 > --- exprs/AddExpr.m3 4 May 2008 11:03:45 -0000 1.3 > +++ exprs/AddExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -67,6 +67,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb, range: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -74,8 +75,9 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.class := Class.cINT; > - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > - p.class := Class.cLINT > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > + p.class := Class.cLINT; > + resultType := LInt.T; > ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN > p.class := Class.cREAL; > ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN > @@ -96,7 +98,11 @@ > ELSE > ta := Expr.BadOperands ("\'+\'", ta, tb); > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: exprs/DivExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/DivExpr.m3,v > retrieving revision 1.5 > diff -u -r1.5 DivExpr.m3 > --- exprs/DivExpr.m3 4 May 2008 11:03:46 -0000 1.5 > +++ exprs/DivExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -60,7 +60,7 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.type := Int.T; > - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > p.type := LInt.T; > ELSE > p.type := Expr.BadOperands ("DIV", ta, tb); > Index: exprs/ModExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/ModExpr.m3,v > retrieving revision 1.5 > diff -u -r1.5 ModExpr.m3 > --- exprs/ModExpr.m3 4 May 2008 11:03:46 -0000 1.5 > +++ exprs/ModExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -60,6 +60,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -67,8 +68,18 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.class := Class.cINT; > + > ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > p.class := Class.cLINT; > + > + (* The result of MOD cannot be higher than either of its inputs. > + * small divided by big is 0 remainder small > + * big divided by small has a remainder of at most small > + *) > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > + p.class := Class.cINT; > + resultType := Int.T; > + > ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN > p.class := Class.cREAL; > ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN > @@ -78,7 +89,11 @@ > ELSE p.class := Class.cERR; ta := Int.T; > ta := Expr.BadOperands ("MOD", ta, tb); > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: exprs/MultiplyExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/MultiplyExpr.m3,v > retrieving revision 1.3 > diff -u -r1.3 MultiplyExpr.m3 > --- exprs/MultiplyExpr.m3 4 May 2008 11:03:46 -0000 1.3 > +++ exprs/MultiplyExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -66,6 +66,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb, range: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -73,8 +74,9 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (tb = Int.T) AND (ta = Int.T) THEN > p.class := cINT; > - ELSIF (tb = LInt.T) AND (ta = LInt.T) THEN > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > p.class := cLINT; > + resultType := LInt.T; > ELSIF (tb = Reel.T) AND (ta = Reel.T) THEN > p.class := cREAL; > ELSIF (tb = LReel.T) AND (ta = LReel.T) THEN > @@ -90,7 +92,11 @@ > ta := Expr.BadOperands ("\'*\'", ta, tb); > p.class := cINT; > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: exprs/SubtractExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/SubtractExpr.m3,v > retrieving revision 1.4 > diff -u -r1.4 SubtractExpr.m3 > --- exprs/SubtractExpr.m3 4 May 2008 11:03:46 -0000 1.4 > +++ exprs/SubtractExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -73,6 +73,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb, range: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -80,8 +81,9 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.class := Class.cINT; > - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > p.class := Class.cLINT; > + resultType := LInt.T; > ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN > p.class := Class.cREAL; > ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN > @@ -113,7 +115,11 @@ > ta := Expr.BadOperands ("\'-\'", ta, tb); > p.class := Class.cINT; > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: types/Type.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/Type.m3,v > retrieving revision 1.8 > diff -u -r1.8 Type.m3 > --- types/Type.m3 4 May 2008 11:03:49 -0000 1.8 > +++ types/Type.m3 8 Jan 2010 07:35:43 -0000 > @@ -543,6 +543,10 @@ > IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN > RETURN TRUE; > ELSIF IsOrdinal (a) THEN > + (* INTEGER is assignable to LONGINT *) > + IF a = LInt.T AND b = Int.T THEN > + RETURN TRUE; > + END; > (* ordinal types: OK if there is a common supertype > and they have at least one member in common. *) > IF IsEqual (Base(a), Base(b), NIL) > > > > > > From rodney_bates at lcwb.coop Fri Jan 8 17:49:06 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 08 Jan 2010 10:49:06 -0600 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , , <527D7354-97E5-47EB-A0FB-FDA7EE3D2B6A@cs.purdue.edu>, <4B468C63.9050404@lcwb.coop> Message-ID: <4B476202.7010004@lcwb.coop> Jay K wrote: > I don't believe currently "10" is assignable > (or comparable) to LONGINT. > You have to use 10L. This is a bit subtle, and I should have been more explicit. I didn't mean the Modula-3 expression "10", I meant just the value ten. From 2.2: ------------------------------------------------------------------------------ Every expression has a unique type, but a value can be a member of many types. For example, the value 6 is a member of both [0..9] and INTEGER. It would be ambiguous to talk about ``the type of a value''. Thus the phrase ``type of x'' means ``type of the expression x'', while ``x is a member of T'' means ``the value of x is a member of T''. ------------------------------------------------------------------------------ The snippets of Modula-3 _code_ "10" and "10L" are expressions. Each has both a value (which is the same) and a type (which is different). The value 10 is a member of both types. The 2.2 quote was written before we had LONGINT and its literals, so referring to the value 6 wasn't as unclear. Maybe it would be better to say that the value 10 when stored in an INTEGER is a different abstract value than 10 stored in a LONGINT. Then the two types would have disjoint value sets. But I think that would be a serious contradiction to the way subranges work. > > > I do believe any INTEGER or CARDINAL expression should be assignable > to LONGINT, but I don't think it is implemented that way currently. > > > And, then, I wonder if subranges are all we need, no LONGINT. > But I don't understand the language well enough. > > > - Jay > From rodney_bates at lcwb.coop Fri Jan 8 17:53:42 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 08 Jan 2010 10:53:42 -0600 Subject: [M3devel] LONGINT, my original proposal Message-ID: <4B476316.4000005@lcwb.coop> Here is my orginal LONGINT proposal, from my own disk file. There were one or two aspects of this I quickly changed, either because I changed my mind on something, or realized something was a specification bug. I am working on rediscovering what they were. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 64-bitProposal URL: From rodney_bates at lcwb.coop Fri Jan 8 18:10:28 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 08 Jan 2010 11:10:28 -0600 Subject: [M3devel] Integers In-Reply-To: <20100108040333.GB9556@topoi.pooq.com> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> Message-ID: <4B476704.8010403@lcwb.coop> hendrik at topoi.pooq.com wrote: > On Thu, Jan 07, 2010 at 01:58:51PM -0500, Tony Hosking wrote: >> I think your confusion relates to understanding how the language >> defines "base" types. >> >> You should understand that INTEGER and LONGINT have *different* base >> types. This indicates that they have inherently different >> representations, > > What's implicit in this statment is that all the subranges of INTEGER > have inherently the same representation. Why is this inportant? Are > there, for example, places in the language where you have a subrange > but don't know what the subrange is? > No, this is not implicit. An implementation can (and probably should) store a variable of a subrange type in a byte or two, if sufficient to hold the range. When the programmer assigns this to an INTEGER, the compiler will have to make a representation change. But is has the necessary information to do this without huge trouble. Similarly, the implementation _must_ store a subrange in a restricted size field when it is a field or array element having a BITS type derived from a subrange type. What's unique about Modula-3 is that such representation changes are left to the compiler, while the language merely views values as sometimes belonging to more than one type, and allows such values to be assigned when so. The usual approach in other languages is to elevate the representation change from a machine-level matter to a language- level matter by treating it as an implicit type change in addition to a representation change. The result is always a lot of unnecessary complexity in the language. >> and indeed, operations on INTEGER and operations on >> LONGINT are inherently different. > > So in the language at present, there is no single type at the top of the > integer type lattice (and it's not really a lattice). There are, > however, two maximal types. Is this right? > >> Every enumeration type similarly has a base type. If it's range is >> expressed over INTEGER values then its base type is INTEGER. If >> expressed over LONGINT then its base type is LONGINT. >> >> I don't think I understand the rest of your questions. > > Where in the language is it important that INTEGER and LONGINT be > different base types? In other words, what advantages does this > separation convey? One thing that is very much needed in a language (not the only thing) is a type that always matches the implementation's native arithmetic size, which is most efficient. If you don't distinguish this type, it becomes either impossible or horribly convoluted to define arithmetic so native machine arithmetic can be usually used where possible, but multi-word arithmetic will be used where needed. > > -- hendrik >> On 7 Jan 2010, at 11:46, hendrik at topoi.pooq.com wrote: >> >>> I have some questions as to the constraints that need to be placed on >>> integral types. These issues are fundamental to an understanding of the >>> role of LONGINT, INTEGER, and CARDINAL, and what we should be doing >>> about them. >>> >>> Is there a need for an integer type that can contain all the sizes of >>> integers that can be handled by the language? I'll call it TOP just so >>> I can talk about it easily. >>> >>> If it is necessary, is TOP only needed to make the language definition >>> clean and concise? Conversely, is it necessary for TOP to be available >>> to programmers? Is it necessary for TOP to be efficiently implemented, >>> or implemented at all? >>> >>> Even if it is not available directly to programmers, are there language >>> features that require it internally? >>> >>> Is it necessary that, for every two integer subranges I and J, there >>> exist an integer range K such that both I and J are subranges of K? >>> >>> The most commonly used integral type is INTEGER. It seems to be the >>> type used by programmers by default when they don't want to think of >>> the specific range they will need. But is it necessary for the type >>> called INTEGER to be TOP? Or, is there is no maximum implemented >>> integral type, is it still necessary for INTEGER to be a maximal >>> integral type? >>> >>> -- hendrik > From mika at async.async.caltech.edu Fri Jan 8 18:34:12 2010 From: mika at async.async.caltech.edu (Mika Nystrom) Date: Fri, 08 Jan 2010 09:34:12 -0800 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> References: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> Message-ID: <20100108173412.8531F1A207A@async.async.caltech.edu> Tony Hosking writes: ... >A type T is assignable to a type U if: > > =95 T <: U, or > =95 U <: T and T is an array or a reference type other than = >ADDRESS (This restriction is lifted in unsafe modules.), or > =95 T and U are ordinal types with at least one member in = >common. > >This suggests that we don't really need to say that INTEGER <: LONGINT. > >We can simply rely on the third clause regarding their both being = >ordinal types with at least one member in common. Then assignment = >simply needs to test that the values are in range. > Are you sure about this for INTEGER and LONGINT? I.e., are 0 and 0L the same "member"? By a similar argument, you could make REAL and LONGREAL assignable. Are 0.0d0 and 0.0e0 the same "thing"? (On almost all machines they have the same bit patterns, same as 0 and 0L for that matter, and I can add that the way you do single-precision floating point on Alpha is by zeroing a big chunk in the middle of your double-precision fp registers...) I think I am with you on removing LONGINT from the language. The proper way of handling file sizes (or anything else that might be a bigger number than a machine word) is through abstraction. I have a suspicion that it's probably a severe micro-optimization to worry about the efficiency of operations on file sizes. The thought that someone is adding automatic type conversion to Modula-3, a la C, makes me feel slightly sick to my stomach... I confess that my position is influenced by the fact that I have written many programs that generate Modula-3 code as an "intermediate language". I really really really need M3 to be easy to understand to get this to work well. Also being able to parse interfaces and know precisely what they mean is important to me. If the rules start getting sloppy.. that would really upset me. On the other hand this means that if I'm faced with a problem that doesn't really fit into M3 well, say, working in arithmetic mod 2^(wordsize), my first instinct is not to demand changes to the language definition but to write a code generator that takes appropriate infix (or maybe more likely prefix) code and turns it into the appropriate calls through the Word interface. It's a pain, yes, but in the long run that's the right way, because you can do so much more with that approach than just unsigned integers. Mika From rcolebur at SCIRES.COM Fri Jan 8 18:36:50 2010 From: rcolebur at SCIRES.COM (Randy Coleburn) Date: Fri, 8 Jan 2010 12:36:50 -0500 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> References: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> Message-ID: I agree with Tony that we need a clean proposal to debate. I also agree with keeping the spirit of the Modula-3 language and type rules. Randy Coleburn -----Original Message----- From: Tony Hosking [mailto:hosking at cs.purdue.edu] Sent: Friday, January 08, 2010 12:00 PM To: Jay K Cc: m3devel Subject: Re: [M3devel] mixing INTEGER and LONGINT? Let's have a clean language proposal before thinking about implementing it... ;-) I continue to oppose mixing operations on both LONGINT and INTEGER. Just as one cannot mix REAL and LONGREAL. I may accept checked assignability between INTEGER and LONGINT (after all, the bits are the same, its just a matter of how many are significant -- unlike REAL/LONGREAL/EXTENDED). Looking further at the assignability rules: A type T is assignable to a type U if: * T <: U, or * U <: T and T is an array or a reference type other than ADDRESS (This restriction is lifted in unsafe modules.), or * T and U are ordinal types with at least one member in common. This suggests that we don't really need to say that INTEGER <: LONGINT. We can simply rely on the third clause regarding their both being ordinal types with at least one member in common. Then assignment simply needs to test that the values are in range. On 8 Jan 2010, at 02:44, Jay K wrote: > This simple diff in the front end allows the "obvious" mixing of INTEGER and LONGINT without any need for ORD or VAL. > > LONGINT + INTEGER => LONGINT > LONGINT - INTEGER => LONGINT > LONGINT * INTEGER => LONGINT > LONGINT DIV INTEGER => LONGINT > INTEGER DIV LONGINT => LONGINT (subtle and I think incorrect, should be INTEGER) > INTEGER MOD LONGINT => INTEGER (subtle but I believe correct) > LONGINT MOD INTEGER => INTEGER (subtle but I believe correct) > MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be INTEGER) > MAX(INTEGER, LONGINT) => LONGINT > LONGINT := INTEGER > > Other mixes are less obvious and would require runtime checks. > > I think the backend will just work but I haven't tried that yet. > (Truth be told, I can only affectively edit files on NT...) > > Thoughts? > > - Jay > > Index: builtinOps/Dec.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Dec.m3,v > retrieving revision 1.9 > diff -u -r1.9 Dec.m3 > --- builtinOps/Dec.m3 25 Sep 2009 02:42:10 -0000 1.9 > +++ builtinOps/Dec.m3 8 Jan 2010 07:35:43 -0000 > @@ -44,7 +44,7 @@ > IF (NUMBER (ce.args^) > 1) THEN > IF Type.IsSubtype (t, LInt.T) THEN > t := Type.Base (Expr.TypeOf (ce.args[1])); > - IF (t # LInt.T) THEN > + IF t # LInt.T AND t # Int.T THEN > Error.Txt (name, "second argument must be a LONGINT"); > END; > ELSE > Index: builtinOps/Max.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Max.m3,v > retrieving revision 1.3 > diff -u -r1.3 Max.m3 > --- builtinOps/Max.m3 18 Sep 2007 20:25:36 -0000 1.3 > +++ builtinOps/Max.m3 8 Jan 2010 07:35:43 -0000 > @@ -25,11 +25,14 @@ > > PROCEDURE DoCheck (name: TEXT; ce: CallExpr.T) = > VAR ta, tb: Type.T; > + resultType: Type.T := NIL; > BEGIN > ta := Type.Base (Expr.TypeOf (ce.args[0])); > tb := Type.Base (Expr.TypeOf (ce.args[1])); > > - IF (NOT Type.IsEqual (ta, tb, NIL)) THEN > + IF (ta = LInt.T AND tb = Int.T) OR (tb = LInt.T AND ta = Int.T) THEN > + resultType := LInt.T; > + ELSIF (NOT Type.IsEqual (ta, tb, NIL)) THEN > Error.Txt (name, "incompatible argument types"); > ELSIF (ta = Int.T) OR (ta = LInt.T) OR (Type.IsOrdinal (ta)) THEN > (* ok *) > @@ -39,7 +42,11 @@ > Error.Txt (name, "wrong argument types"); > ta := Int.T; > END; > - ce.type := ta; > + IF resultType # NIL THEN > + ce.type := resultType; > + ELSE > + ce.type := ta; > + END; > END DoCheck; > > PROCEDURE Compile (ce: CallExpr.T) = > Index: exprs/AddExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/AddExpr.m3,v > retrieving revision 1.3 > diff -u -r1.3 AddExpr.m3 > --- exprs/AddExpr.m3 4 May 2008 11:03:45 -0000 1.3 > +++ exprs/AddExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -67,6 +67,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb, range: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -74,8 +75,9 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.class := Class.cINT; > - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > - p.class := Class.cLINT > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > + p.class := Class.cLINT; > + resultType := LInt.T; > ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN > p.class := Class.cREAL; > ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN > @@ -96,7 +98,11 @@ > ELSE > ta := Expr.BadOperands ("\'+\'", ta, tb); > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: exprs/DivExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/DivExpr.m3,v > retrieving revision 1.5 > diff -u -r1.5 DivExpr.m3 > --- exprs/DivExpr.m3 4 May 2008 11:03:46 -0000 1.5 > +++ exprs/DivExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -60,7 +60,7 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.type := Int.T; > - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > p.type := LInt.T; > ELSE > p.type := Expr.BadOperands ("DIV", ta, tb); > Index: exprs/ModExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/ModExpr.m3,v > retrieving revision 1.5 > diff -u -r1.5 ModExpr.m3 > --- exprs/ModExpr.m3 4 May 2008 11:03:46 -0000 1.5 > +++ exprs/ModExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -60,6 +60,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -67,8 +68,18 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.class := Class.cINT; > + > ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > p.class := Class.cLINT; > + > + (* The result of MOD cannot be higher than either of its inputs. > + * small divided by big is 0 remainder small > + * big divided by small has a remainder of at most small > + *) > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > + p.class := Class.cINT; > + resultType := Int.T; > + > ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN > p.class := Class.cREAL; > ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN > @@ -78,7 +89,11 @@ > ELSE p.class := Class.cERR; ta := Int.T; > ta := Expr.BadOperands ("MOD", ta, tb); > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: exprs/MultiplyExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/MultiplyExpr.m3,v > retrieving revision 1.3 > diff -u -r1.3 MultiplyExpr.m3 > --- exprs/MultiplyExpr.m3 4 May 2008 11:03:46 -0000 1.3 > +++ exprs/MultiplyExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -66,6 +66,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb, range: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -73,8 +74,9 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (tb = Int.T) AND (ta = Int.T) THEN > p.class := cINT; > - ELSIF (tb = LInt.T) AND (ta = LInt.T) THEN > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > p.class := cLINT; > + resultType := LInt.T; > ELSIF (tb = Reel.T) AND (ta = Reel.T) THEN > p.class := cREAL; > ELSIF (tb = LReel.T) AND (ta = LReel.T) THEN > @@ -90,7 +92,11 @@ > ta := Expr.BadOperands ("\'*\'", ta, tb); > p.class := cINT; > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: exprs/SubtractExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/SubtractExpr.m3,v > retrieving revision 1.4 > diff -u -r1.4 SubtractExpr.m3 > --- exprs/SubtractExpr.m3 4 May 2008 11:03:46 -0000 1.4 > +++ exprs/SubtractExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -73,6 +73,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb, range: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -80,8 +81,9 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.class := Class.cINT; > - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > p.class := Class.cLINT; > + resultType := LInt.T; > ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN > p.class := Class.cREAL; > ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN > @@ -113,7 +115,11 @@ > ta := Expr.BadOperands ("\'-\'", ta, tb); > p.class := Class.cINT; > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: types/Type.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/Type.m3,v > retrieving revision 1.8 > diff -u -r1.8 Type.m3 > --- types/Type.m3 4 May 2008 11:03:49 -0000 1.8 > +++ types/Type.m3 8 Jan 2010 07:35:43 -0000 > @@ -543,6 +543,10 @@ > IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN > RETURN TRUE; > ELSIF IsOrdinal (a) THEN > + (* INTEGER is assignable to LONGINT *) > + IF a = LInt.T AND b = Int.T THEN > + RETURN TRUE; > + END; > (* ordinal types: OK if there is a common supertype > and they have at least one member in common. *) > IF IsEqual (Base(a), Base(b), NIL) > > > > > > From rodney_bates at lcwb.coop Fri Jan 8 18:33:52 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 08 Jan 2010 11:33:52 -0600 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: References: Message-ID: <4B476C80.4090601@lcwb.coop> Jay K wrote: > This simple diff in the front end allows the "obvious" mixing of INTEGER > and LONGINT without any need for ORD or VAL. > > LONGINT + INTEGER => LONGINT > LONGINT - INTEGER => LONGINT > LONGINT * INTEGER => LONGINT > LONGINT DIV INTEGER => LONGINT > INTEGER DIV LONGINT => LONGINT (subtle and I think incorrect, should > be INTEGER) > INTEGER MOD LONGINT => INTEGER (subtle but I believe correct) > LONGINT MOD INTEGER => INTEGER (subtle but I believe correct) > MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be > INTEGER) > MAX(INTEGER, LONGINT) => LONGINT > LONGINT := INTEGER Making INTEGER and LONGINT mutually assignable (or even one-way assignability of INTEGER to LONGINT) implies all of the above. The arithmetic operators are defined as generalizations of Modula-3 procedures, with parameters of VALUE mode. And the rule for VALUE requires only that the actual be assignable to the formal, not have identical type. This is what I originally proposed. Actually, with LONGINT in the picture, the arithmetic operators have to be defined more carefully, in order to avoid or remove ambiguity in resolution of builtin overloaded arithmetic operators. Particularly, we have to eliminate the possibility that, e.g., an expression of the form INTEGER INTEGER would resolve to the LONGINT LONGINT -> LONGINT operator, by assignability of INTEGER to LONGINT. This would completely the efficiency of native machine arithmetic. Whatever we do, I feel very strongly that we should preserve consistency with both the existing rules that assignment statements and passing VALUE parameters require assignability. That means that explicitly coded VAL/ORD functions will be required either in both assignments and mixed arithmetic, or neither. The same applies to a number of other places that require assignability. > > Other mixes are less obvious and would require runtime checks. > > I think the backend will just work but I haven't tried that yet. > (Truth be told, I can only affectively edit files on NT...) > > Thoughts? > > - Jay > > Index: builtinOps/Dec.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Dec.m3,v > retrieving revision 1.9 > diff -u -r1.9 Dec.m3 > --- builtinOps/Dec.m3 25 Sep 2009 02:42:10 -0000 1.9 > +++ builtinOps/Dec.m3 8 Jan 2010 07:35:43 -0000 > @@ -44,7 +44,7 @@ > IF (NUMBER (ce.args^) > 1) THEN > IF Type.IsSubtype (t, LInt.T) THEN > t := Type.Base (Expr.TypeOf (ce.args[1])); > - IF (t # LInt.T) THEN > + IF t # LInt.T AND t # Int.T THEN > Error.Txt (name, "second argument must be a LONGINT"); > END; > ELSE > Index: builtinOps/Max.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Max.m3,v > retrieving revision 1.3 > diff -u -r1.3 Max.m3 > --- builtinOps/Max.m3 18 Sep 2007 20:25:36 -0000 1.3 > +++ builtinOps/Max.m3 8 Jan 2010 07:35:43 -0000 > @@ -25,11 +25,14 @@ > > PROCEDURE DoCheck (name: TEXT; ce: CallExpr.T) = > VAR ta, tb: Type.T; > + resultType: Type.T := NIL; > BEGIN > ta := Type.Base (Expr.TypeOf (ce.args[0])); > tb := Type.Base (Expr.TypeOf (ce.args[1])); > > - IF (NOT Type.IsEqual (ta, tb, NIL)) THEN > + IF (ta = LInt.T AND tb = Int.T) OR (tb = LInt.T AND ta = Int.T) THEN > + resultType := LInt.T; > + ELSIF (NOT Type.IsEqual (ta, tb, NIL)) THEN > Error.Txt (name, "incompatible argument types"); > ELSIF (ta = Int.T) OR (ta = LInt.T) OR (Type.IsOrdinal (ta)) THEN > (* ok *) > @@ -39,7 +42,11 @@ > Error.Txt (name, "wrong argument types"); > ta := Int.T; > END; > - ce.type := ta; > + IF resultType # NIL THEN > + ce.type := resultType; > + ELSE > + ce.type := ta; > + END; > END DoCheck; > > PROCEDURE Compile (ce: CallExpr.T) = > Index: exprs/AddExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/AddExpr.m3,v > retrieving revision 1.3 > diff -u -r1.3 AddExpr.m3 > --- exprs/AddExpr.m3 4 May 2008 11:03:45 -0000 1.3 > +++ exprs/AddExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -67,6 +67,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb, range: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -74,8 +75,9 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.class := Class.cINT; > - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > - p.class := Class.cLINT > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > + p.class := Class.cLINT; > + resultType := LInt.T; > ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN > p.class := Class.cREAL; > ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN > @@ -96,7 +98,11 @@ > ELSE > ta := Expr.BadOperands ("\'+\'", ta, tb); > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: exprs/DivExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/DivExpr.m3,v > retrieving revision 1.5 > diff -u -r1.5 DivExpr.m3 > --- exprs/DivExpr.m3 4 May 2008 11:03:46 -0000 1.5 > +++ exprs/DivExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -60,7 +60,7 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.type := Int.T; > - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > p.type := LInt.T; > ELSE > p.type := Expr.BadOperands ("DIV", ta, tb); > Index: exprs/ModExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/ModExpr.m3,v > retrieving revision 1.5 > diff -u -r1.5 ModExpr.m3 > --- exprs/ModExpr.m3 4 May 2008 11:03:46 -0000 1.5 > +++ exprs/ModExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -60,6 +60,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -67,8 +68,18 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.class := Class.cINT; > + > ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > p.class := Class.cLINT; > + > + (* The result of MOD cannot be higher than either of its inputs. > + * small divided by big is 0 remainder small > + * big divided by small has a remainder of at most small > + *) > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > + p.class := Class.cINT; > + resultType := Int.T; > + > ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN > p.class := Class.cREAL; > ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN > @@ -78,7 +89,11 @@ > ELSE p.class := Class.cERR; ta := Int.T; > ta := Expr.BadOperands ("MOD", ta, tb); > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: exprs/MultiplyExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/MultiplyExpr.m3,v > retrieving revision 1.3 > diff -u -r1.3 MultiplyExpr.m3 > --- exprs/MultiplyExpr.m3 4 May 2008 11:03:46 -0000 1.3 > +++ exprs/MultiplyExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -66,6 +66,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb, range: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -73,8 +74,9 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (tb = Int.T) AND (ta = Int.T) THEN > p.class := cINT; > - ELSIF (tb = LInt.T) AND (ta = LInt.T) THEN > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > p.class := cLINT; > + resultType := LInt.T; > ELSIF (tb = Reel.T) AND (ta = Reel.T) THEN > p.class := cREAL; > ELSIF (tb = LReel.T) AND (ta = LReel.T) THEN > @@ -90,7 +92,11 @@ > ta := Expr.BadOperands ("\'*\'", ta, tb); > p.class := cINT; > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: exprs/SubtractExpr.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/SubtractExpr.m3,v > retrieving revision 1.4 > diff -u -r1.4 SubtractExpr.m3 > --- exprs/SubtractExpr.m3 4 May 2008 11:03:46 -0000 1.4 > +++ exprs/SubtractExpr.m3 8 Jan 2010 07:35:43 -0000 > @@ -73,6 +73,7 @@ > > PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = > VAR ta, tb, range: Type.T; > + resultType: Type.T := NIL; > BEGIN > Expr.TypeCheck (p.a, cs); > Expr.TypeCheck (p.b, cs); > @@ -80,8 +81,9 @@ > tb := Type.Base (Expr.TypeOf (p.b)); > IF (ta = Int.T) AND (tb = Int.T) THEN > p.class := Class.cINT; > - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN > + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN > p.class := Class.cLINT; > + resultType := LInt.T; > ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN > p.class := Class.cREAL; > ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN > @@ -113,7 +115,11 @@ > ta := Expr.BadOperands ("\'-\'", ta, tb); > p.class := Class.cINT; > END; > - p.type := ta; > + IF resultType # NIL THEN > + p.type := resultType; > + ELSE > + p.type := ta; > + END; > END Check; > > PROCEDURE Prep (p: P) = > Index: types/Type.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/Type.m3,v > retrieving revision 1.8 > diff -u -r1.8 Type.m3 > --- types/Type.m3 4 May 2008 11:03:49 -0000 1.8 > +++ types/Type.m3 8 Jan 2010 07:35:43 -0000 > @@ -543,6 +543,10 @@ > IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN > RETURN TRUE; > ELSIF IsOrdinal (a) THEN > + (* INTEGER is assignable to LONGINT *) > + IF a = LInt.T AND b = Int.T THEN > + RETURN TRUE; > + END; > (* ordinal types: OK if there is a common supertype > and they have at least one member in common. *) > IF IsEqual (Base(a), Base(b), NIL) > > > > > > From hosking at cs.purdue.edu Fri Jan 8 19:00:50 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 13:00:50 -0500 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: <4B476316.4000005@lcwb.coop> References: <4B476316.4000005@lcwb.coop> Message-ID: <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu> We already have much of this, but not all. Notes below... I am now convinced (Jay will be relieved) that Rodney's proposal is mostly what we want. I am looking into making the changes to the current implementation that will bring this into being. On 8 Jan 2010, at 11:53, Rodney M. Bates wrote: > Here is my orginal LONGINT proposal, from my own disk file. There were one or two > aspects of this I quickly changed, either because I changed my mind on something, > or realized something was a specification bug. I am working on rediscovering what > they were. > A proposal for Modula-3 language changes to support an integer type > larger than the native size of the target processor. > > This proposal satisfies (I believe) the following principles: > > The static correctness and type analysis of existing code written to > the current language definition will not change with the new > definition. This also implies that the new language definition will > not introduce new type mismatches that would make existing pickles > unreadable. > > The runtime semantics and time and space efficiency of existing code > written to the current language definition will also not change with > the new definition, if the native word size of the implementation does > not change. Of course, porting existing code to an implementation > with different native word size can change the runtime semantics by > changing the supported value range, with or without language change. > > The static type analysis of programs written to the modified language > definition will be independent of the implementation, particularly, of > the native word size. This prevents inadvertently writing code that > is highly nonportable among different native word sizes. > > The new, not-necessarily-native integer type does not extend to > certain existing uses of INTEGER and CARDINAL that are of unlikely > utility and would add complexity. > > Actual statements about the language are numbered. Comments are > indented more deeply, following a numbered item they apply to. Some > numbered items are labeled "NO CHANGE", and merely call attention to > the lack of a change, where it is relevant or calls for comment. > > Changes to the language proper: > > 1. There is a new builtin type named LONGINT. We have this. > 2. FIRST(LONGINT) <= FIRST(INTEGER) and LAST(INTEGER) <= LAST(LONGINT). Currently, direct comparison between LONGINT and INTEGER is not permitted. If it were then this would be true. > The intent is that INTEGER will remain as the native integer > size on the implemented processor. LONGINT might be bigger, but > not necessarily. Typically, on a 32-bit processor, LONGINT > would be 64 bits. On a 64-bit processor, it could be 64 or 128. This is what we currently have. > 3. There are new literals of type LONGINT, denoted by following a > nonempty sequence of digits by either 'l' or 'L'. We have this right now. > Having distinctly spelled literals preserves Modula-3's clean > system of referentially transparent typing, i.e, the type of > every expression is determined by the expression alone, without > regard to how it is used. The 3 floating point types already > follow this principle. Literals of ambiguous type, combined > with a system of implicit conversions taken from the context > would create a semantic mess. (e.g. Ada). I wholeheartedly agree! > I believe intuitively that Id, LOCK, and LOOP are not members of > FOLLOW(Number), but need to check this mechanically. It would > mean that the new literals can not undermine any existing, > compilable code. The current implementation illustrates that this is not a problem. > 4. LONGINT # INTEGER. We have this right now. > This is true regardless of whether their ranges are equal. This > keeps the typing independent of the implementation. Doing > otherwise could be a portability nightmare. Agreed. > 5. LONGINT is an ordinal type. We have this right now. > This means the existing rules of assignability will allow > assignment between LONGINT and its subtypes and INTEGER and its > subtypes, with the usual runtime value check, when required. I will go ahead and implement assignability with the appropriate value checks. This will eliminate the need for explicit ORD/VAL conversions. > 6. Neither LONGINT nor INTEGER is a subtype of the other. We have this right now. > This is true regardless of whether their ranges are equal, in > part for the same reason the types are unequal. > > Note that, for ordinal types, assignability doesn't actually use > the subtype relation. In fact, the one place I can find in the > present language where subtypes matter for ordinal types is in > the definition of signatures of operators, etc. In 2.6.1, > paragraph 5, operands must have a subtype of the type specified. > Keeping LONGINT and INTEGER subtype-unrelated keeps this > statement unambiguous and allows easy specification of the > operators. Agreed. > 7. Prefix operators +, -, and ABS can take an operand having a > subtype of LONGINT, in which case, their result has type LONGINT. We have this. > 8. Infix operators +, -, DIV, MOD, MIN, and MAX, can accept a pair of > operands that are subtypes of a mixture of INTEGER and LONGINT. > If either is a subtype of LONGINT, the result has type LONGINT, > otherwise INTEGER. The result is correct (i.e., no overflow > occurs) if the result value is a member of the result type. I am uneasy about mixing parameter types in this way. I note that current implementation of these operations permit overflow because the overflow result is still a member of the result type. > With assignment between different subranges, Modula-3 takes the > view that this is not an implied type conversion at all. > Instead, the rules have the effect that if the value is a member > of the LHS type, then it's OK. I think this is a brilliant > piece of language design. Compare to the many pages of > description that C++ and Java require to define implied type > conversions in assignments, and they only have a few > integer-like types, whereas current Modula-3 has, typically, > ~2^31 subrange types involved. It's also less > implementation-oriented, because it doesn't appeal to bit > representations, etc. Agreed. > I resisted allowing mixed sizes of operands, until I realized we > can do the same thing with operators as with assignment, i.e., > just require result values to be in range, without calling > anything an implied type conversion. This is part of my uneasiness. I guess I am willing to accept that the type of the operation is the maximal type of its operands. > A compiler can implement this by just doing the arithmetic in > the same size as the result type. This means if both operands > are subtypes of INTEGER, (which will always be the case with > existing code,) then the native arithmetic will be used, without > loss of efficiency. OK. I think I see how to implement this... > 9. Relational operators =, #, <, >, <=, and >=, can accept a pair of > operands that are subtypes of a mixture of INTEGER and LONGINT. > > Again, a compiler can figure out how to generate code for this, > with no loss of efficiency when both are subtypes of INTEGER. Same as above. I think it can be implemented. > 10. The first parameter to FLOAT can have a subtype of either INTEGER > or LONGINT. We already support this. > 11. FLOOR, CEILING, ROUND, and TRUNC have an optional second > parameter, which can be either LONGINT or INTEGER, and which > specifies the result type of the operation. If omitted, it > defaults to INTEGER. The result has this type. > > The default preserves existing code. Already supported. > 12. The result type of ORD is LONGINT if the parameter is a subtype of > LONGINT, otherwise it remains INTEGER. The current implementation uses ORD as the mechanism for checked conversion from LONGINT to INTEGER. If we change assignability as you suggest then we no longer need explicit conversion so we can support the semantics you describe. > There is really not much programmer value in applying ORD to a > subtype of either INTEGER or LONGINT, since this is just an > identity on the value. It would provide an explicit, widening > type conversion, and NARROW won't accomplish this, because it is > only defined on reference types. However, this rule provides > consistency, and maybe would simplify some machine-generated > source code scheme. > > This fails to support an implementation's effort to expand the > number of values of an enumeration type beyond the current > implied limitation of the positive native word values. How > tough. I see no problem with the maximum enumeration type values being restricted to natural integers. > 13. The first parameter to VAL can be a subtype of either INTEGER or > LONGINT. > > Beside generalizing the existing uses of VAL, this also allows > explicit conversions between LONGINT and INTEGER, if there is > any need for them. The current implementation uses VAL as the mechanism for conversion from INTEGER to LONGINT. Just like ORD, if we change assignability as you suggest then we can support your semantics as an explicit conversion. > 14. (NO CHANGE) The safe definitions of INC and DEC do not change. > > As a consequence of the changes to +, -, ORD, and VAL, the > existing equivalent WITH-statement definition will generalize to > mixes of any ordinal type for the first parameter and a subtype > of either INTEGER or LONGINT for the second. [Note that I just fixed a bug in the implementation of INC/DEC to make it properly equivalent to the WITH-statement definition.] The current implementation does not allow mixing INTEGER/LONGINT operand and increments. > 15. There is a new builtin type named LONGCARD. It "behaves just > like" (but is not equal to) [0..LAST(LONGINT)]. > > The current CARDINAL has an interesting history. Originally, it > was just a predefined name for the type [0..LAST(INTEGER)]. It > was later changed to be "just like" the subrange, i.e., the two > are not the same type, but have the same properties in every > other respect. The only reason for the change had to do with > reading pickles, which are completely defined and implemented as > library code. The change did affect the type analysis of the > language, nevertheless. > > We should preserve this property for LONGCARD too. Currently there is no implementation of LONGCARD. I argue that we don't need LONGCARD (since, as discussed below, NUMBER should stay typed as CARDINAL), unless LONGCARD is needed for pickles... Rodney? > 16. Neither LONGINT, nor any subtype thereof, can be used as the index > type of an array type. This is the current implementation. > One could think about allowing this, but it would require a lot > of other things to be generalized, and is unlikely to be of much > use. Agreed. > After the world's having had to learn twice the hard way, what a > mess that comes from addresses that are larger than the native > arithmetic size, we are unlikely to see it again. So, the only > ways a longer LONGINT index type could be of any use are: 1) > arrays of elements no bigger than a byte, that occupy more than > half the entire addressable memory, and you want to avoid > negative index values, or 2) arrays of packed elements less than > byte size that occupy at least one eighth of the memory (or some > mixture thereof). All these cases also can occur only when > using close to the maximum addressable virtual memory. Not very > likely. > > If you really need 64-bit array subscripts, you will have to use > an implementation whose native size is 64 bits. > > This also avoids generalizing SUBARRAY, several procedures in > required interface TEXT, more extensive generalization of > NUMBER, etc. > > 17. Neither LONGINT, nor any subtype thereof, can be used as the base > type of a set type. This is the current implementation. > This is similar to the array index limitation. Sets on base > types of long range are very unlikely, as they would be too bit. > The assignability rules should make subranges of INTEGER > relatively easy to use as set base types instead of short > subranges of LONGINT. This also obviates generalizing IN. Agreed. > 18. The result type of NUMBER is LONGCARD if its parameter is a > subtype of LONGINT, otherwise INTEGER, as currently. > > NUMBER has always had the messy problem that its correct value > can lie beyond the upper limit of its result type CARDINAL. > Fortunately, it is rare to use it in cases where this happens. > The expanded definition still has the equivalent problem, but it > seems even less likely to actually happen. > > One could consider making NUMBER always return a LONGCARD, which > would fix the problem for parameters that are INTEGER, but that > would not preserve existing semantics or efficiency. The current implementation leaves the result of NUMBER as CARDINAL. The reasoning for this is that NUMBER is only really useful for dealing in the sizes of arrays, etc. (which as noted above retain bounds that can be expressed in natural INTEGERs). > 19. (NO CHANGE) BITSIZE, BYTESIZE, ADRSIZE, and TYPECODE are unchanged. This is the current implementation. > > If you really need 64-bit sizes or typecodes, you will have to > use an implementation whose native size is 64 bits. Agreed. > 20. The statement that the upperbound of a FOR loop should not be > LAST(INTEGER) also applies to LAST(LONGINT). Agreed. > Note that the existing definition of FOR otherwise generalizes > to LONGINT without change. The current implementation does not permit the range values to be different types (both must be INTEGER or LONGINT), and the step value must also match. Will we permit any mixing of values? If so, I assume that we use the maximal type of the expressions (LONGINT if any one is LONGINT, INTEGER otherwise). > Changes to required (AKA standard) interfaces: > > 21. (NO CHANGE). The INTEGER parameters to Word.Shift and > Word.Rotate, and the CARDINAL parameters of Word.Extract and > Word.Insert are unchanged. > > These are bit numbers. There is no need for a longer range. This is the current implementation. > 22. There is a new required interface LongWord. It almost exactly > parallels Word, except 1) LongWord.T = LONGINT, and 2) it contains > new functions ToWord and FromWord, that conversion between the two > types, using unsigned interpretations of the values. ToInt may > produce a checked runtime error, if the result value is not in the > range of an unsigned interpretation of INTEGER. This is the current implementation, but we do not support ToWord and FromWord. Why do we need these? > Word.T = INTEGER, so LongWord.T should = LONGINT, for > consistency. This means simple assignability tests and > assignments between the types will use signed interpretations. > So different functions are needed to do size changes with > unsigned interpretation. This is the current implementation. > 23. (NO CHANGE) The Base and Precision values in required interfaces > Real, LongReal, and Extended, keep the type INTEGER. > > There is no need for increased value range here. This is the current implementation. > 24. (NO CHANGE) Float.Scalb, which has a parameter of type INTEGER, > and Float.ILogb, whose result type is INTEGER, do not have LONGINT > counterparts. > > It is difficult to imagine these values needing greater range. This is the current implementation. > 25. Fmt has a new function LongInt, parallel to Int, but replacing > INTEGER by LONGINT. We have this. > 26. Lex has a new function LongInt, parallel to Int, but replacing > INTEGER by LONGINT. We have this. > 27. There is a new required interface named LongAddress. It is UNSAFE > and contains procedures that are equivalents for the 5 unsafe > ADDRESS arithmetic operations, with LONGINT substituted in place > of INTEGER in their signatures. These are given in 2.7 and > include a +, two overloaded meanings of -, an INC, and a DEC. We currently do not support this. > It is remotely conceivable that there could be a target whose > native address size is longer than its native integer size > (unlike the reverse.) In such a case, these operations might be > needed. Until we see the need I hesitate to implement it. > Four of them could be accommodated by just generalizing the > INTEGER parameter to allow either INTEGER or LONGINT. The > remaining operator subtracts two ADDRESS operands and returns an > INTEGER. This can't be generalized using Modula-3's existing > pattern of overload resolution of builtin operations. > Redefining it to always do LONGINT arithmetic would violate the > existing efficiency criterion. Two separate operations are > needed. > > This solution avoids complexity in the language proper, while > still accommodating a rare requirement. It could probably be > left unimplemented unless/until such a target actually happens. Agreed. > Changes to useful interfaces: > > 28. IO has new procedures PutLongInt and GetLongInt, parallel to > PutInt and GetInt. I just added these. > I have not looked systematically at all the useful interfaces > for other places that use CARDINAL and INTEGER and might need to > be generalized. (Can anyone point to a tool that will grep > files in .ps or .pdf format, or something equivalent?) > > Note that changes in nonrequired interfaces should be > implementable just by writing new/modified library code, without > additional help from the compiler. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Jan 8 19:08:46 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 13:08:46 -0500 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: <20100108173412.8531F1A207A@async.async.caltech.edu> References: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> <20100108173412.8531F1A207A@async.async.caltech.edu> Message-ID: <3BB40DAB-60F8-461E-A9C8-FF80A81F74A8@cs.purdue.edu> On 8 Jan 2010, at 12:34, Mika Nystrom wrote: > Tony Hosking writes: > ... >> A type T is assignable to a type U if: >> >> =95 T <: U, or >> =95 U <: T and T is an array or a reference type other than = >> ADDRESS (This restriction is lifted in unsafe modules.), or >> =95 T and U are ordinal types with at least one member in = >> common. >> >> This suggests that we don't really need to say that INTEGER <: LONGINT. >> >> We can simply rely on the third clause regarding their both being = >> ordinal types with at least one member in common. Then assignment = >> simply needs to test that the values are in range. >> > > Are you sure about this for INTEGER and LONGINT? I.e., are 0 and 0L > the same "member"? Yes, we could potentially do that. It is straightforward because their significant bits are the same. > By a similar argument, you could make REAL and LONGREAL assignable. > Are 0.0d0 and 0.0e0 the same "thing"? (On almost all machines they have > the same bit patterns, same as 0 and 0L for that matter, and I can add > that the way you do single-precision floating point on Alpha is by zeroing > a big chunk in the middle of your double-precision fp registers...) Not so reasonable, because their bits are different and need explicit conversion. > I think I am with you on removing LONGINT from the language. The proper > way of handling file sizes (or anything else that might be a bigger number > than a machine word) is through abstraction. I have a suspicion that it's > probably a severe micro-optimization to worry about the efficiency of > operations on file sizes. The thought that someone is adding automatic > type conversion to Modula-3, a la C, makes me feel slightly sick to > my stomach... I agree with those sentiments. While LONGINT can be accomodated (and more elegantly if we evolve towards Rodney's proposal -- see my other e-mail) I am still not convinced that it is worth all the complications. If LONGINT is there only for large file sizes then abstraction is a *much* better way to go. Why add a general-purpose type for a one-off use-case? > I confess that my position is influenced by the fact that I have written > many programs that generate Modula-3 code as an "intermediate language". > I really really really need M3 to be easy to understand to get this to > work well. Also being able to parse interfaces and know precisely what > they mean is important to me. If the rules start getting sloppy.. that > would really upset me. On the other hand this means that if I'm faced > with a problem that doesn't really fit into M3 well, say, working in > arithmetic mod 2^(wordsize), my first instinct is not to demand changes > to the language definition but to write a code generator that takes > appropriate infix (or maybe more likely prefix) code and turns it into > the appropriate calls through the Word interface. It's a pain, yes, > but in the long run that's the right way, because you can do so much > more with that approach than just unsigned integers. Agreed. From hosking at cs.purdue.edu Fri Jan 8 19:19:58 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 13:19:58 -0500 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: <4B476C80.4090601@lcwb.coop> References: <4B476C80.4090601@lcwb.coop> Message-ID: <18553308-F36F-44B9-857F-E53B859B02C0@cs.purdue.edu> To summarise the discussion so far... 1. Do we really need LONGINT? Some have expressed a desire for it. The only use-case so far is large file sizes. 2. If we do need LONGINT then Rodney's proposal seems sound apart from the question of resolution of the builtin overloaded arithmetic operators. Rodney's proposal is that they resolve to the maximal type of their operands. Jay, I am very concerned about your definitions for MOD/DIV below because I think they are inherently unintuitive (witness your own claims of "subtlety" -- Modula-3 should not ever have subtle semantics!). I forget what the rules for C happen to be... (with good reason since I've never wanted to try to remember them and avoid mixed type operands like the plague!). So, do I hear strong arguments for or against mixed type integer operands? On 8 Jan 2010, at 12:33, Rodney M. Bates wrote: > > > Jay K wrote: >> This simple diff in the front end allows the "obvious" mixing of INTEGER and LONGINT without any need for ORD or VAL. >> LONGINT + INTEGER => LONGINT >> LONGINT - INTEGER => LONGINT >> LONGINT * INTEGER => LONGINT >> LONGINT DIV INTEGER => LONGINT >> INTEGER DIV LONGINT => LONGINT (subtle and I think incorrect, should be INTEGER) >> INTEGER MOD LONGINT => INTEGER (subtle but I believe correct) LONGINT MOD INTEGER => INTEGER (subtle but I believe correct) MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be INTEGER) MAX(INTEGER, LONGINT) => LONGINT LONGINT := INTEGER > > Making INTEGER and LONGINT mutually assignable (or even one-way > assignability of INTEGER to LONGINT) implies all of the above. > The arithmetic operators are defined as generalizations of Modula-3 > procedures, with parameters of VALUE mode. And the rule for VALUE > requires only that the actual be assignable to the formal, not > have identical type. This is what I originally proposed. > > Actually, with LONGINT in the picture, the arithmetic operators have > to be defined more carefully, in order to avoid or remove ambiguity in > resolution of builtin overloaded arithmetic operators. Particularly, > we have to eliminate the possibility that, e.g., an expression of the form > INTEGER INTEGER would resolve to the LONGINT LONGINT -> LONGINT > operator, by assignability of INTEGER to LONGINT. This would completely > the efficiency of native machine arithmetic. > > Whatever we do, I feel very strongly that we should preserve consistency > with both the existing rules that assignment statements and passing > VALUE parameters require assignability. That means that explicitly coded > VAL/ORD functions will be required either in both assignments and mixed > arithmetic, or neither. The same applies to a number of other places > that require assignability. > > >> Other mixes are less obvious and would require runtime checks. >> I think the backend will just work but I haven't tried that yet. >> (Truth be told, I can only affectively edit files on NT...) >> Thoughts? >> - Jay >> Index: builtinOps/Dec.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Dec.m3,v >> retrieving revision 1.9 >> diff -u -r1.9 Dec.m3 >> --- builtinOps/Dec.m3 25 Sep 2009 02:42:10 -0000 1.9 >> +++ builtinOps/Dec.m3 8 Jan 2010 07:35:43 -0000 >> @@ -44,7 +44,7 @@ >> IF (NUMBER (ce.args^) > 1) THEN >> IF Type.IsSubtype (t, LInt.T) THEN >> t := Type.Base (Expr.TypeOf (ce.args[1])); >> - IF (t # LInt.T) THEN >> + IF t # LInt.T AND t # Int.T THEN >> Error.Txt (name, "second argument must be a LONGINT"); >> END; >> ELSE >> Index: builtinOps/Max.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Max.m3,v >> retrieving revision 1.3 >> diff -u -r1.3 Max.m3 >> --- builtinOps/Max.m3 18 Sep 2007 20:25:36 -0000 1.3 >> +++ builtinOps/Max.m3 8 Jan 2010 07:35:43 -0000 >> @@ -25,11 +25,14 @@ >> PROCEDURE DoCheck (name: TEXT; ce: CallExpr.T) = >> VAR ta, tb: Type.T; >> + resultType: Type.T := NIL; >> BEGIN >> ta := Type.Base (Expr.TypeOf (ce.args[0])); >> tb := Type.Base (Expr.TypeOf (ce.args[1])); >> - IF (NOT Type.IsEqual (ta, tb, NIL)) THEN >> + IF (ta = LInt.T AND tb = Int.T) OR (tb = LInt.T AND ta = Int.T) THEN >> + resultType := LInt.T; >> + ELSIF (NOT Type.IsEqual (ta, tb, NIL)) THEN >> Error.Txt (name, "incompatible argument types"); >> ELSIF (ta = Int.T) OR (ta = LInt.T) OR (Type.IsOrdinal (ta)) THEN >> (* ok *) >> @@ -39,7 +42,11 @@ >> Error.Txt (name, "wrong argument types"); >> ta := Int.T; >> END; >> - ce.type := ta; >> + IF resultType # NIL THEN >> + ce.type := resultType; >> + ELSE >> + ce.type := ta; >> + END; >> END DoCheck; >> PROCEDURE Compile (ce: CallExpr.T) = >> Index: exprs/AddExpr.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/AddExpr.m3,v >> retrieving revision 1.3 >> diff -u -r1.3 AddExpr.m3 >> --- exprs/AddExpr.m3 4 May 2008 11:03:45 -0000 1.3 >> +++ exprs/AddExpr.m3 8 Jan 2010 07:35:43 -0000 >> @@ -67,6 +67,7 @@ >> PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = >> VAR ta, tb, range: Type.T; >> + resultType: Type.T := NIL; >> BEGIN >> Expr.TypeCheck (p.a, cs); >> Expr.TypeCheck (p.b, cs); >> @@ -74,8 +75,9 @@ >> tb := Type.Base (Expr.TypeOf (p.b)); >> IF (ta = Int.T) AND (tb = Int.T) THEN >> p.class := Class.cINT; >> - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN >> - p.class := Class.cLINT >> + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN >> + p.class := Class.cLINT; >> + resultType := LInt.T; >> ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN >> p.class := Class.cREAL; >> ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN >> @@ -96,7 +98,11 @@ >> ELSE >> ta := Expr.BadOperands ("\'+\'", ta, tb); >> END; >> - p.type := ta; >> + IF resultType # NIL THEN >> + p.type := resultType; >> + ELSE >> + p.type := ta; >> + END; >> END Check; >> PROCEDURE Prep (p: P) = >> Index: exprs/DivExpr.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/DivExpr.m3,v >> retrieving revision 1.5 >> diff -u -r1.5 DivExpr.m3 >> --- exprs/DivExpr.m3 4 May 2008 11:03:46 -0000 1.5 >> +++ exprs/DivExpr.m3 8 Jan 2010 07:35:43 -0000 >> @@ -60,7 +60,7 @@ >> tb := Type.Base (Expr.TypeOf (p.b)); >> IF (ta = Int.T) AND (tb = Int.T) THEN >> p.type := Int.T; >> - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN >> + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN >> p.type := LInt.T; >> ELSE >> p.type := Expr.BadOperands ("DIV", ta, tb); >> Index: exprs/ModExpr.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/ModExpr.m3,v >> retrieving revision 1.5 >> diff -u -r1.5 ModExpr.m3 >> --- exprs/ModExpr.m3 4 May 2008 11:03:46 -0000 1.5 >> +++ exprs/ModExpr.m3 8 Jan 2010 07:35:43 -0000 >> @@ -60,6 +60,7 @@ >> PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = >> VAR ta, tb: Type.T; >> + resultType: Type.T := NIL; >> BEGIN >> Expr.TypeCheck (p.a, cs); >> Expr.TypeCheck (p.b, cs); >> @@ -67,8 +68,18 @@ >> tb := Type.Base (Expr.TypeOf (p.b)); >> IF (ta = Int.T) AND (tb = Int.T) THEN >> p.class := Class.cINT; >> + >> ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN >> p.class := Class.cLINT; >> + >> + (* The result of MOD cannot be higher than either of its inputs. >> + * small divided by big is 0 remainder small >> + * big divided by small has a remainder of at most small >> + *) >> + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN >> + p.class := Class.cINT; >> + resultType := Int.T; >> + >> ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN >> p.class := Class.cREAL; >> ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN >> @@ -78,7 +89,11 @@ >> ELSE p.class := Class.cERR; ta := Int.T; >> ta := Expr.BadOperands ("MOD", ta, tb); >> END; >> - p.type := ta; >> + IF resultType # NIL THEN >> + p.type := resultType; >> + ELSE >> + p.type := ta; >> + END; >> END Check; >> PROCEDURE Prep (p: P) = >> Index: exprs/MultiplyExpr.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/MultiplyExpr.m3,v >> retrieving revision 1.3 >> diff -u -r1.3 MultiplyExpr.m3 >> --- exprs/MultiplyExpr.m3 4 May 2008 11:03:46 -0000 1.3 >> +++ exprs/MultiplyExpr.m3 8 Jan 2010 07:35:43 -0000 >> @@ -66,6 +66,7 @@ >> PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = >> VAR ta, tb, range: Type.T; >> + resultType: Type.T := NIL; >> BEGIN >> Expr.TypeCheck (p.a, cs); >> Expr.TypeCheck (p.b, cs); >> @@ -73,8 +74,9 @@ >> tb := Type.Base (Expr.TypeOf (p.b)); >> IF (tb = Int.T) AND (ta = Int.T) THEN >> p.class := cINT; >> - ELSIF (tb = LInt.T) AND (ta = LInt.T) THEN >> + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN >> p.class := cLINT; >> + resultType := LInt.T; >> ELSIF (tb = Reel.T) AND (ta = Reel.T) THEN >> p.class := cREAL; >> ELSIF (tb = LReel.T) AND (ta = LReel.T) THEN >> @@ -90,7 +92,11 @@ >> ta := Expr.BadOperands ("\'*\'", ta, tb); >> p.class := cINT; >> END; >> - p.type := ta; >> + IF resultType # NIL THEN >> + p.type := resultType; >> + ELSE >> + p.type := ta; >> + END; >> END Check; >> PROCEDURE Prep (p: P) = >> Index: exprs/SubtractExpr.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/SubtractExpr.m3,v >> retrieving revision 1.4 >> diff -u -r1.4 SubtractExpr.m3 >> --- exprs/SubtractExpr.m3 4 May 2008 11:03:46 -0000 1.4 >> +++ exprs/SubtractExpr.m3 8 Jan 2010 07:35:43 -0000 >> @@ -73,6 +73,7 @@ >> PROCEDURE Check (p: P; VAR cs: Expr.CheckState) = >> VAR ta, tb, range: Type.T; >> + resultType: Type.T := NIL; >> BEGIN >> Expr.TypeCheck (p.a, cs); >> Expr.TypeCheck (p.b, cs); >> @@ -80,8 +81,9 @@ >> tb := Type.Base (Expr.TypeOf (p.b)); >> IF (ta = Int.T) AND (tb = Int.T) THEN >> p.class := Class.cINT; >> - ELSIF (ta = LInt.T) AND (tb = LInt.T) THEN >> + ELSIF (ta = LInt.T OR ta = Int.T) AND (tb = LInt.T OR tb = Int.T) THEN >> p.class := Class.cLINT; >> + resultType := LInt.T; >> ELSIF (ta = Reel.T) AND (tb = Reel.T) THEN >> p.class := Class.cREAL; >> ELSIF (ta = LReel.T) AND (tb = LReel.T) THEN >> @@ -113,7 +115,11 @@ >> ta := Expr.BadOperands ("\'-\'", ta, tb); >> p.class := Class.cINT; >> END; >> - p.type := ta; >> + IF resultType # NIL THEN >> + p.type := resultType; >> + ELSE >> + p.type := ta; >> + END; >> END Check; >> PROCEDURE Prep (p: P) = >> Index: types/Type.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/Type.m3,v >> retrieving revision 1.8 >> diff -u -r1.8 Type.m3 >> --- types/Type.m3 4 May 2008 11:03:49 -0000 1.8 >> +++ types/Type.m3 8 Jan 2010 07:35:43 -0000 >> @@ -543,6 +543,10 @@ >> IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN >> RETURN TRUE; >> ELSIF IsOrdinal (a) THEN >> + (* INTEGER is assignable to LONGINT *) >> + IF a = LInt.T AND b = Int.T THEN >> + RETURN TRUE; >> + END; >> (* ordinal types: OK if there is a common supertype >> and they have at least one member in common. *) >> IF IsEqual (Base(a), Base(b), NIL) -------------- next part -------------- An HTML attachment was scrubbed... URL: From rcolebur at SCIRES.COM Fri Jan 8 19:20:50 2010 From: rcolebur at SCIRES.COM (Randy Coleburn) Date: Fri, 8 Jan 2010 13:20:50 -0500 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu> References: <4B476316.4000005@lcwb.coop> <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu> Message-ID: Whenever all this is nailed down, someone needs to put together a set of diffs to NELSON SPwM3, and update the reference section in "cm3/doc" and the language posters in "cm3/doc/src_reports". Randy Coleburn From: Tony Hosking [mailto:hosking at cs.purdue.edu] Sent: Friday, January 08, 2010 1:01 PM To: Rodney M. Bates Cc: m3devel Subject: Re: [M3devel] LONGINT, my original proposal We already have much of this, but not all. Notes below... I am now convinced (Jay will be relieved) that Rodney's proposal is mostly what we want. I am looking into making the changes to the current implementation that will bring this into being. On 8 Jan 2010, at 11:53, Rodney M. Bates wrote: Here is my orginal LONGINT proposal, from my own disk file. There were one or two aspects of this I quickly changed, either because I changed my mind on something, or realized something was a specification bug. I am working on rediscovering what they were. A proposal for Modula-3 language changes to support an integer type larger than the native size of the target processor. This proposal satisfies (I believe) the following principles: The static correctness and type analysis of existing code written to the current language definition will not change with the new definition. This also implies that the new language definition will not introduce new type mismatches that would make existing pickles unreadable. The runtime semantics and time and space efficiency of existing code written to the current language definition will also not change with the new definition, if the native word size of the implementation does not change. Of course, porting existing code to an implementation with different native word size can change the runtime semantics by changing the supported value range, with or without language change. The static type analysis of programs written to the modified language definition will be independent of the implementation, particularly, of the native word size. This prevents inadvertently writing code that is highly nonportable among different native word sizes. The new, not-necessarily-native integer type does not extend to certain existing uses of INTEGER and CARDINAL that are of unlikely utility and would add complexity. Actual statements about the language are numbered. Comments are indented more deeply, following a numbered item they apply to. Some numbered items are labeled "NO CHANGE", and merely call attention to the lack of a change, where it is relevant or calls for comment. Changes to the language proper: 1. There is a new builtin type named LONGINT. We have this. 2. FIRST(LONGINT) <= FIRST(INTEGER) and LAST(INTEGER) <= LAST(LONGINT). Currently, direct comparison between LONGINT and INTEGER is not permitted. If it were then this would be true. The intent is that INTEGER will remain as the native integer size on the implemented processor. LONGINT might be bigger, but not necessarily. Typically, on a 32-bit processor, LONGINT would be 64 bits. On a 64-bit processor, it could be 64 or 128. This is what we currently have. 3. There are new literals of type LONGINT, denoted by following a nonempty sequence of digits by either 'l' or 'L'. We have this right now. Having distinctly spelled literals preserves Modula-3's clean system of referentially transparent typing, i.e, the type of every expression is determined by the expression alone, without regard to how it is used. The 3 floating point types already follow this principle. Literals of ambiguous type, combined with a system of implicit conversions taken from the context would create a semantic mess. (e.g. Ada). I wholeheartedly agree! I believe intuitively that Id, LOCK, and LOOP are not members of FOLLOW(Number), but need to check this mechanically. It would mean that the new literals can not undermine any existing, compilable code. The current implementation illustrates that this is not a problem. 4. LONGINT # INTEGER. We have this right now. This is true regardless of whether their ranges are equal. This keeps the typing independent of the implementation. Doing otherwise could be a portability nightmare. Agreed. 5. LONGINT is an ordinal type. We have this right now. This means the existing rules of assignability will allow assignment between LONGINT and its subtypes and INTEGER and its subtypes, with the usual runtime value check, when required. I will go ahead and implement assignability with the appropriate value checks. This will eliminate the need for explicit ORD/VAL conversions. 6. Neither LONGINT nor INTEGER is a subtype of the other. We have this right now. This is true regardless of whether their ranges are equal, in part for the same reason the types are unequal. Note that, for ordinal types, assignability doesn't actually use the subtype relation. In fact, the one place I can find in the present language where subtypes matter for ordinal types is in the definition of signatures of operators, etc. In 2.6.1, paragraph 5, operands must have a subtype of the type specified. Keeping LONGINT and INTEGER subtype-unrelated keeps this statement unambiguous and allows easy specification of the operators. Agreed. 7. Prefix operators +, -, and ABS can take an operand having a subtype of LONGINT, in which case, their result has type LONGINT. We have this. 8. Infix operators +, -, DIV, MOD, MIN, and MAX, can accept a pair of operands that are subtypes of a mixture of INTEGER and LONGINT. If either is a subtype of LONGINT, the result has type LONGINT, otherwise INTEGER. The result is correct (i.e., no overflow occurs) if the result value is a member of the result type. I am uneasy about mixing parameter types in this way. I note that current implementation of these operations permit overflow because the overflow result is still a member of the result type. With assignment between different subranges, Modula-3 takes the view that this is not an implied type conversion at all. Instead, the rules have the effect that if the value is a member of the LHS type, then it's OK. I think this is a brilliant piece of language design. Compare to the many pages of description that C++ and Java require to define implied type conversions in assignments, and they only have a few integer-like types, whereas current Modula-3 has, typically, ~2^31 subrange types involved. It's also less implementation-oriented, because it doesn't appeal to bit representations, etc. Agreed. I resisted allowing mixed sizes of operands, until I realized we can do the same thing with operators as with assignment, i.e., just require result values to be in range, without calling anything an implied type conversion. This is part of my uneasiness. I guess I am willing to accept that the type of the operation is the maximal type of its operands. A compiler can implement this by just doing the arithmetic in the same size as the result type. This means if both operands are subtypes of INTEGER, (which will always be the case with existing code,) then the native arithmetic will be used, without loss of efficiency. OK. I think I see how to implement this... 9. Relational operators =, #, <, >, <=, and >=, can accept a pair of operands that are subtypes of a mixture of INTEGER and LONGINT. Again, a compiler can figure out how to generate code for this, with no loss of efficiency when both are subtypes of INTEGER. Same as above. I think it can be implemented. 10. The first parameter to FLOAT can have a subtype of either INTEGER or LONGINT. We already support this. 11. FLOOR, CEILING, ROUND, and TRUNC have an optional second parameter, which can be either LONGINT or INTEGER, and which specifies the result type of the operation. If omitted, it defaults to INTEGER. The result has this type. The default preserves existing code. Already supported. 12. The result type of ORD is LONGINT if the parameter is a subtype of LONGINT, otherwise it remains INTEGER. The current implementation uses ORD as the mechanism for checked conversion from LONGINT to INTEGER. If we change assignability as you suggest then we no longer need explicit conversion so we can support the semantics you describe. There is really not much programmer value in applying ORD to a subtype of either INTEGER or LONGINT, since this is just an identity on the value. It would provide an explicit, widening type conversion, and NARROW won't accomplish this, because it is only defined on reference types. However, this rule provides consistency, and maybe would simplify some machine-generated source code scheme. This fails to support an implementation's effort to expand the number of values of an enumeration type beyond the current implied limitation of the positive native word values. How tough. I see no problem with the maximum enumeration type values being restricted to natural integers. 13. The first parameter to VAL can be a subtype of either INTEGER or LONGINT. Beside generalizing the existing uses of VAL, this also allows explicit conversions between LONGINT and INTEGER, if there is any need for them. The current implementation uses VAL as the mechanism for conversion from INTEGER to LONGINT. Just like ORD, if we change assignability as you suggest then we can support your semantics as an explicit conversion. 14. (NO CHANGE) The safe definitions of INC and DEC do not change. As a consequence of the changes to +, -, ORD, and VAL, the existing equivalent WITH-statement definition will generalize to mixes of any ordinal type for the first parameter and a subtype of either INTEGER or LONGINT for the second. [Note that I just fixed a bug in the implementation of INC/DEC to make it properly equivalent to the WITH-statement definition.] The current implementation does not allow mixing INTEGER/LONGINT operand and increments. 15. There is a new builtin type named LONGCARD. It "behaves just like" (but is not equal to) [0..LAST(LONGINT)]. The current CARDINAL has an interesting history. Originally, it was just a predefined name for the type [0..LAST(INTEGER)]. It was later changed to be "just like" the subrange, i.e., the two are not the same type, but have the same properties in every other respect. The only reason for the change had to do with reading pickles, which are completely defined and implemented as library code. The change did affect the type analysis of the language, nevertheless. We should preserve this property for LONGCARD too. Currently there is no implementation of LONGCARD. I argue that we don't need LONGCARD (since, as discussed below, NUMBER should stay typed as CARDINAL), unless LONGCARD is needed for pickles... Rodney? 16. Neither LONGINT, nor any subtype thereof, can be used as the index type of an array type. This is the current implementation. One could think about allowing this, but it would require a lot of other things to be generalized, and is unlikely to be of much use. Agreed. After the world's having had to learn twice the hard way, what a mess that comes from addresses that are larger than the native arithmetic size, we are unlikely to see it again. So, the only ways a longer LONGINT index type could be of any use are: 1) arrays of elements no bigger than a byte, that occupy more than half the entire addressable memory, and you want to avoid negative index values, or 2) arrays of packed elements less than byte size that occupy at least one eighth of the memory (or some mixture thereof). All these cases also can occur only when using close to the maximum addressable virtual memory. Not very likely. If you really need 64-bit array subscripts, you will have to use an implementation whose native size is 64 bits. This also avoids generalizing SUBARRAY, several procedures in required interface TEXT, more extensive generalization of NUMBER, etc. 17. Neither LONGINT, nor any subtype thereof, can be used as the base type of a set type. This is the current implementation. This is similar to the array index limitation. Sets on base types of long range are very unlikely, as they would be too bit. The assignability rules should make subranges of INTEGER relatively easy to use as set base types instead of short subranges of LONGINT. This also obviates generalizing IN. Agreed. 18. The result type of NUMBER is LONGCARD if its parameter is a subtype of LONGINT, otherwise INTEGER, as currently. NUMBER has always had the messy problem that its correct value can lie beyond the upper limit of its result type CARDINAL. Fortunately, it is rare to use it in cases where this happens. The expanded definition still has the equivalent problem, but it seems even less likely to actually happen. One could consider making NUMBER always return a LONGCARD, which would fix the problem for parameters that are INTEGER, but that would not preserve existing semantics or efficiency. The current implementation leaves the result of NUMBER as CARDINAL. The reasoning for this is that NUMBER is only really useful for dealing in the sizes of arrays, etc. (which as noted above retain bounds that can be expressed in natural INTEGERs). 19. (NO CHANGE) BITSIZE, BYTESIZE, ADRSIZE, and TYPECODE are unchanged. This is the current implementation. If you really need 64-bit sizes or typecodes, you will have to use an implementation whose native size is 64 bits. Agreed. 20. The statement that the upperbound of a FOR loop should not be LAST(INTEGER) also applies to LAST(LONGINT). Agreed. Note that the existing definition of FOR otherwise generalizes to LONGINT without change. The current implementation does not permit the range values to be different types (both must be INTEGER or LONGINT), and the step value must also match. Will we permit any mixing of values? If so, I assume that we use the maximal type of the expressions (LONGINT if any one is LONGINT, INTEGER otherwise). Changes to required (AKA standard) interfaces: 21. (NO CHANGE). The INTEGER parameters to Word.Shift and Word.Rotate, and the CARDINAL parameters of Word.Extract and Word.Insert are unchanged. These are bit numbers. There is no need for a longer range. This is the current implementation. 22. There is a new required interface LongWord. It almost exactly parallels Word, except 1) LongWord.T = LONGINT, and 2) it contains new functions ToWord and FromWord, that conversion between the two types, using unsigned interpretations of the values. ToInt may produce a checked runtime error, if the result value is not in the range of an unsigned interpretation of INTEGER. This is the current implementation, but we do not support ToWord and FromWord. Why do we need these? Word.T = INTEGER, so LongWord.T should = LONGINT, for consistency. This means simple assignability tests and assignments between the types will use signed interpretations. So different functions are needed to do size changes with unsigned interpretation. This is the current implementation. 23. (NO CHANGE) The Base and Precision values in required interfaces Real, LongReal, and Extended, keep the type INTEGER. There is no need for increased value range here. This is the current implementation. 24. (NO CHANGE) Float.Scalb, which has a parameter of type INTEGER, and Float.ILogb, whose result type is INTEGER, do not have LONGINT counterparts. It is difficult to imagine these values needing greater range. This is the current implementation. 25. Fmt has a new function LongInt, parallel to Int, but replacing INTEGER by LONGINT. We have this. 26. Lex has a new function LongInt, parallel to Int, but replacing INTEGER by LONGINT. We have this. 27. There is a new required interface named LongAddress. It is UNSAFE and contains procedures that are equivalents for the 5 unsafe ADDRESS arithmetic operations, with LONGINT substituted in place of INTEGER in their signatures. These are given in 2.7 and include a +, two overloaded meanings of -, an INC, and a DEC. We currently do not support this. It is remotely conceivable that there could be a target whose native address size is longer than its native integer size (unlike the reverse.) In such a case, these operations might be needed. Until we see the need I hesitate to implement it. Four of them could be accommodated by just generalizing the INTEGER parameter to allow either INTEGER or LONGINT. The remaining operator subtracts two ADDRESS operands and returns an INTEGER. This can't be generalized using Modula-3's existing pattern of overload resolution of builtin operations. Redefining it to always do LONGINT arithmetic would violate the existing efficiency criterion. Two separate operations are needed. This solution avoids complexity in the language proper, while still accommodating a rare requirement. It could probably be left unimplemented unless/until such a target actually happens. Agreed. Changes to useful interfaces: 28. IO has new procedures PutLongInt and GetLongInt, parallel to PutInt and GetInt. I just added these. I have not looked systematically at all the useful interfaces for other places that use CARDINAL and INTEGER and might need to be generalized. (Can anyone point to a tool that will grep files in .ps or .pdf format, or something equivalent?) Note that changes in nonrequired interfaces should be implementable just by writing new/modified library code, without additional help from the compiler. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Jan 8 19:25:10 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 13:25:10 -0500 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: References: <4B476316.4000005@lcwb.coop> <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu> Message-ID: <4020F84F-CF80-4C0B-8586-FD7D7AD8F052@cs.purdue.edu> I've already made changes to cm3/doc/reference that match the current implementation (no implicit assignability). I'm happy to adjust that to match what we eventually implement. On 8 Jan 2010, at 13:20, Randy Coleburn wrote: > Whenever all this is nailed down, someone needs to put together a set of diffs to NELSON SPwM3, and update the reference section in ?cm3/doc? and the language posters in ?cm3/doc/src_reports?. > > Randy Coleburn > > > From: Tony Hosking [mailto:hosking at cs.purdue.edu] > Sent: Friday, January 08, 2010 1:01 PM > To: Rodney M. Bates > Cc: m3devel > Subject: Re: [M3devel] LONGINT, my original proposal > > We already have much of this, but not all. Notes below... > > I am now convinced (Jay will be relieved) that Rodney's proposal is mostly what we want. > > I am looking into making the changes to the current implementation that will bring this into being. > > On 8 Jan 2010, at 11:53, Rodney M. Bates wrote: > > > Here is my orginal LONGINT proposal, from my own disk file. There were one or two > aspects of this I quickly changed, either because I changed my mind on something, > or realized something was a specification bug. I am working on rediscovering what > they were. > A proposal for Modula-3 language changes to support an integer type > larger than the native size of the target processor. > > This proposal satisfies (I believe) the following principles: > > The static correctness and type analysis of existing code written to > the current language definition will not change with the new > definition. This also implies that the new language definition will > not introduce new type mismatches that would make existing pickles > unreadable. > > The runtime semantics and time and space efficiency of existing code > written to the current language definition will also not change with > the new definition, if the native word size of the implementation does > not change. Of course, porting existing code to an implementation > with different native word size can change the runtime semantics by > changing the supported value range, with or without language change. > > The static type analysis of programs written to the modified language > definition will be independent of the implementation, particularly, of > the native word size. This prevents inadvertently writing code that > is highly nonportable among different native word sizes. > > The new, not-necessarily-native integer type does not extend to > certain existing uses of INTEGER and CARDINAL that are of unlikely > utility and would add complexity. > > Actual statements about the language are numbered. Comments are > indented more deeply, following a numbered item they apply to. Some > numbered items are labeled "NO CHANGE", and merely call attention to > the lack of a change, where it is relevant or calls for comment. > > Changes to the language proper: > > 1. There is a new builtin type named LONGINT. > > We have this. > > > 2. FIRST(LONGINT) <= FIRST(INTEGER) and LAST(INTEGER) <= LAST(LONGINT). > > Currently, direct comparison between LONGINT and INTEGER is not permitted. If it were then this would be true. > > > The intent is that INTEGER will remain as the native integer > size on the implemented processor. LONGINT might be bigger, but > not necessarily. Typically, on a 32-bit processor, LONGINT > would be 64 bits. On a 64-bit processor, it could be 64 or 128. > > This is what we currently have. > > > 3. There are new literals of type LONGINT, denoted by following a > nonempty sequence of digits by either 'l' or 'L'. > > We have this right now. > > > Having distinctly spelled literals preserves Modula-3's clean > system of referentially transparent typing, i.e, the type of > every expression is determined by the expression alone, without > regard to how it is used. The 3 floating point types already > follow this principle. Literals of ambiguous type, combined > with a system of implicit conversions taken from the context > would create a semantic mess. (e.g. Ada). > > I wholeheartedly agree! > > > I believe intuitively that Id, LOCK, and LOOP are not members of > FOLLOW(Number), but need to check this mechanically. It would > mean that the new literals can not undermine any existing, > compilable code. > > The current implementation illustrates that this is not a problem. > > > 4. LONGINT # INTEGER. > > We have this right now. > > > This is true regardless of whether their ranges are equal. This > keeps the typing independent of the implementation. Doing > otherwise could be a portability nightmare. > > Agreed. > > > 5. LONGINT is an ordinal type. > > We have this right now. > > > This means the existing rules of assignability will allow > assignment between LONGINT and its subtypes and INTEGER and its > subtypes, with the usual runtime value check, when required. > > I will go ahead and implement assignability with the appropriate value checks. This will eliminate the need for explicit ORD/VAL conversions. > > > 6. Neither LONGINT nor INTEGER is a subtype of the other. > > We have this right now. > > > This is true regardless of whether their ranges are equal, in > part for the same reason the types are unequal. > > Note that, for ordinal types, assignability doesn't actually use > the subtype relation. In fact, the one place I can find in the > present language where subtypes matter for ordinal types is in > the definition of signatures of operators, etc. In 2.6.1, > paragraph 5, operands must have a subtype of the type specified. > Keeping LONGINT and INTEGER subtype-unrelated keeps this > statement unambiguous and allows easy specification of the > operators. > > Agreed. > > > 7. Prefix operators +, -, and ABS can take an operand having a > subtype of LONGINT, in which case, their result has type LONGINT. > > We have this. > > > 8. Infix operators +, -, DIV, MOD, MIN, and MAX, can accept a pair of > operands that are subtypes of a mixture of INTEGER and LONGINT. > If either is a subtype of LONGINT, the result has type LONGINT, > otherwise INTEGER. The result is correct (i.e., no overflow > occurs) if the result value is a member of the result type. > > I am uneasy about mixing parameter types in this way. > I note that current implementation of these operations permit overflow because the overflow result is still a member of the result type. > > > With assignment between different subranges, Modula-3 takes the > view that this is not an implied type conversion at all. > Instead, the rules have the effect that if the value is a member > of the LHS type, then it's OK. I think this is a brilliant > piece of language design. Compare to the many pages of > description that C++ and Java require to define implied type > conversions in assignments, and they only have a few > integer-like types, whereas current Modula-3 has, typically, > ~2^31 subrange types involved. It's also less > implementation-oriented, because it doesn't appeal to bit > representations, etc. > > Agreed. > > > I resisted allowing mixed sizes of operands, until I realized we > can do the same thing with operators as with assignment, i.e., > just require result values to be in range, without calling > anything an implied type conversion. > > This is part of my uneasiness. I guess I am willing to accept that the type of the operation is the maximal type of its operands. > > > A compiler can implement this by just doing the arithmetic in > the same size as the result type. This means if both operands > are subtypes of INTEGER, (which will always be the case with > existing code,) then the native arithmetic will be used, without > loss of efficiency. > > OK. I think I see how to implement this... > > > 9. Relational operators =, #, <, >, <=, and >=, can accept a pair of > operands that are subtypes of a mixture of INTEGER and LONGINT. > > Again, a compiler can figure out how to generate code for this, > with no loss of efficiency when both are subtypes of INTEGER. > > Same as above. I think it can be implemented. > > > 10. The first parameter to FLOAT can have a subtype of either INTEGER > or LONGINT. > > We already support this. > > > 11. FLOOR, CEILING, ROUND, and TRUNC have an optional second > parameter, which can be either LONGINT or INTEGER, and which > specifies the result type of the operation. If omitted, it > defaults to INTEGER. The result has this type. > > The default preserves existing code. > > Already supported. > > > 12. The result type of ORD is LONGINT if the parameter is a subtype of > LONGINT, otherwise it remains INTEGER. > > The current implementation uses ORD as the mechanism for checked conversion from LONGINT to INTEGER. > If we change assignability as you suggest then we no longer need explicit conversion so we can support the semantics you describe. > > > There is really not much programmer value in applying ORD to a > subtype of either INTEGER or LONGINT, since this is just an > identity on the value. It would provide an explicit, widening > type conversion, and NARROW won't accomplish this, because it is > only defined on reference types. However, this rule provides > consistency, and maybe would simplify some machine-generated > source code scheme. > > This fails to support an implementation's effort to expand the > number of values of an enumeration type beyond the current > implied limitation of the positive native word values. How > tough. > > I see no problem with the maximum enumeration type values being restricted to natural integers. > > > 13. The first parameter to VAL can be a subtype of either INTEGER or > LONGINT. > > Beside generalizing the existing uses of VAL, this also allows > explicit conversions between LONGINT and INTEGER, if there is > any need for them. > > The current implementation uses VAL as the mechanism for conversion from INTEGER to LONGINT. > Just like ORD, if we change assignability as you suggest then we can support your semantics as an explicit conversion. > > > 14. (NO CHANGE) The safe definitions of INC and DEC do not change. > > As a consequence of the changes to +, -, ORD, and VAL, the > existing equivalent WITH-statement definition will generalize to > mixes of any ordinal type for the first parameter and a subtype > of either INTEGER or LONGINT for the second. > > [Note that I just fixed a bug in the implementation of INC/DEC to make it properly equivalent to the WITH-statement definition.] > The current implementation does not allow mixing INTEGER/LONGINT operand and increments. > > 15. There is a new builtin type named LONGCARD. It "behaves just > like" (but is not equal to) [0..LAST(LONGINT)]. > > The current CARDINAL has an interesting history. Originally, it > was just a predefined name for the type [0..LAST(INTEGER)]. It > was later changed to be "just like" the subrange, i.e., the two > are not the same type, but have the same properties in every > other respect. The only reason for the change had to do with > reading pickles, which are completely defined and implemented as > library code. The change did affect the type analysis of the > language, nevertheless. > > We should preserve this property for LONGCARD too. > > Currently there is no implementation of LONGCARD. I argue that we don't need LONGCARD (since, as discussed below, NUMBER should stay typed as CARDINAL), unless LONGCARD is needed for pickles... Rodney? > > > 16. Neither LONGINT, nor any subtype thereof, can be used as the index > type of an array type. > > This is the current implementation. > > > One could think about allowing this, but it would require a lot > of other things to be generalized, and is unlikely to be of much > use. > > Agreed. > > > After the world's having had to learn twice the hard way, what a > mess that comes from addresses that are larger than the native > arithmetic size, we are unlikely to see it again. So, the only > ways a longer LONGINT index type could be of any use are: 1) > arrays of elements no bigger than a byte, that occupy more than > half the entire addressable memory, and you want to avoid > negative index values, or 2) arrays of packed elements less than > byte size that occupy at least one eighth of the memory (or some > mixture thereof). All these cases also can occur only when > using close to the maximum addressable virtual memory. Not very > likely. > > If you really need 64-bit array subscripts, you will have to use > an implementation whose native size is 64 bits. > > This also avoids generalizing SUBARRAY, several procedures in > required interface TEXT, more extensive generalization of > NUMBER, etc. > > 17. Neither LONGINT, nor any subtype thereof, can be used as the base > type of a set type. > > This is the current implementation. > > > This is similar to the array index limitation. Sets on base > types of long range are very unlikely, as they would be too bit. > The assignability rules should make subranges of INTEGER > relatively easy to use as set base types instead of short > subranges of LONGINT. This also obviates generalizing IN. > > Agreed. > > > 18. The result type of NUMBER is LONGCARD if its parameter is a > subtype of LONGINT, otherwise INTEGER, as currently. > > NUMBER has always had the messy problem that its correct value > can lie beyond the upper limit of its result type CARDINAL. > Fortunately, it is rare to use it in cases where this happens. > The expanded definition still has the equivalent problem, but it > seems even less likely to actually happen. > > One could consider making NUMBER always return a LONGCARD, which > would fix the problem for parameters that are INTEGER, but that > would not preserve existing semantics or efficiency. > > The current implementation leaves the result of NUMBER as CARDINAL. The reasoning for this is that NUMBER is only really useful for dealing in the sizes of arrays, etc. (which as noted above retain bounds that can be expressed in natural INTEGERs). > > > 19. (NO CHANGE) BITSIZE, BYTESIZE, ADRSIZE, and TYPECODE are unchanged. > > This is the current implementation. > > > If you really need 64-bit sizes or typecodes, you will have to > use an implementation whose native size is 64 bits. > > Agreed. > > > 20. The statement that the upperbound of a FOR loop should not be > LAST(INTEGER) also applies to LAST(LONGINT). > > Agreed. > > > Note that the existing definition of FOR otherwise generalizes > to LONGINT without change. > > The current implementation does not permit the range values to be different types (both must be INTEGER or LONGINT), and the step value must also match. Will we permit any mixing of values? If so, I assume that we use the maximal type of the expressions (LONGINT if any one is LONGINT, INTEGER otherwise). > > > Changes to required (AKA standard) interfaces: > > 21. (NO CHANGE). The INTEGER parameters to Word.Shift and > Word.Rotate, and the CARDINAL parameters of Word.Extract and > Word.Insert are unchanged. > > These are bit numbers. There is no need for a longer range. > > This is the current implementation. > > > 22. There is a new required interface LongWord. It almost exactly > parallels Word, except 1) LongWord.T = LONGINT, and 2) it contains > new functions ToWord and FromWord, that conversion between the two > types, using unsigned interpretations of the values. ToInt may > produce a checked runtime error, if the result value is not in the > range of an unsigned interpretation of INTEGER. > > This is the current implementation, but we do not support ToWord and FromWord. Why do we need these? > > > Word.T = INTEGER, so LongWord.T should = LONGINT, for > consistency. This means simple assignability tests and > assignments between the types will use signed interpretations. > So different functions are needed to do size changes with > unsigned interpretation. > > This is the current implementation. > > > 23. (NO CHANGE) The Base and Precision values in required interfaces > Real, LongReal, and Extended, keep the type INTEGER. > > There is no need for increased value range here. > > This is the current implementation. > > > 24. (NO CHANGE) Float.Scalb, which has a parameter of type INTEGER, > and Float.ILogb, whose result type is INTEGER, do not have LONGINT > counterparts. > > It is difficult to imagine these values needing greater range. > > This is the current implementation. > > > 25. Fmt has a new function LongInt, parallel to Int, but replacing > INTEGER by LONGINT. > > We have this. > > > 26. Lex has a new function LongInt, parallel to Int, but replacing > INTEGER by LONGINT. > > We have this. > > > 27. There is a new required interface named LongAddress. It is UNSAFE > and contains procedures that are equivalents for the 5 unsafe > ADDRESS arithmetic operations, with LONGINT substituted in place > of INTEGER in their signatures. These are given in 2.7 and > include a +, two overloaded meanings of -, an INC, and a DEC. > > We currently do not support this. > > > It is remotely conceivable that there could be a target whose > native address size is longer than its native integer size > (unlike the reverse.) In such a case, these operations might be > needed. > > Until we see the need I hesitate to implement it. > > > Four of them could be accommodated by just generalizing the > INTEGER parameter to allow either INTEGER or LONGINT. The > remaining operator subtracts two ADDRESS operands and returns an > INTEGER. This can't be generalized using Modula-3's existing > pattern of overload resolution of builtin operations. > Redefining it to always do LONGINT arithmetic would violate the > existing efficiency criterion. Two separate operations are > needed. > > This solution avoids complexity in the language proper, while > still accommodating a rare requirement. It could probably be > left unimplemented unless/until such a target actually happens. > > Agreed. > > > Changes to useful interfaces: > > 28. IO has new procedures PutLongInt and GetLongInt, parallel to > PutInt and GetInt. > > I just added these. > > > I have not looked systematically at all the useful interfaces > for other places that use CARDINAL and INTEGER and might need to > be generalized. (Can anyone point to a tool that will grep > files in .ps or .pdf format, or something equivalent?) > > Note that changes in nonrequired interfaces should be > implementable just by writing new/modified library code, without > additional help from the compiler. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hendrik at topoi.pooq.com Fri Jan 8 19:34:17 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 13:34:17 -0500 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: <4B476316.4000005@lcwb.coop> References: <4B476316.4000005@lcwb.coop> Message-ID: <20100108183416.GC14151@topoi.pooq.com> On Fri, Jan 08, 2010 at 10:53:42AM -0600, Rodney M. Bates wrote: > > 17. Neither LONGINT, nor any subtype thereof, can be used as the base > type of a set type. > > This is similar to the array index limitation. Sets on base > types of long range are very unlikely, as they would be too bit. "too big", not "too bit" > The assignability rules should make subranges of INTEGER > relatively easy to use as set base types instead of short > subranges of LONGINT. This also obviates generalizing IN. > > 27. There is a new required interface named LongAddress. It is UNSAFE > and contains procedures that are equivalents for the 5 unsafe > ADDRESS arithmetic operations, with LONGINT substituted in place > of INTEGER in their signatures. These are given in 2.7 and > include a +, two overloaded meanings of -, an INC, and a DEC. > > It is remotely conceivable that there could be a target whose > native address size is longer than its native integer size > (unlike the reverse.) In such a case, these operations might be > needed. The IBM 360 had three-byte addresses, but a four-byte integer. However, they had to be four-byte aligned, and were usually handled using four-byte operations. However, OS code (in assembler) often stuffer various non-address flags in the extra byte, so except for its massive obsolescence, this would be a real consideration. The IBM 370 had special instructions for loading and storing the three address bytes of a machine word, making this a little cleaner. I'm told a later version of this architecture switched to four-byte addresses, causing a very expensive rewrite of a huge amount of code. -- hendrik From hendrik at topoi.pooq.com Fri Jan 8 19:54:53 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 13:54:53 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100108114448.3fukoteb40og04og@mail.elegosoft.com> References: <20100107131117.GA22266@topoi.pooq.com> <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> <2E21F50B-4710-4123-BB1F-FDF77CDB8C59@cs.purdue.edu> <20100108114448.3fukoteb40og04og@mail.elegosoft.com> Message-ID: <20100108185453.GD14151@topoi.pooq.com> On Fri, Jan 08, 2010 at 11:44:48AM +0100, Olaf Wagner wrote: > > Just my opinion of course. I don't really understand why you are so > drastically opposing LONGINT suddenly. Probably I haven't been able to > follow some of the arguments. I could understand opposition to LONGINT if it were based on it being a kludge stuck in to quickly patch a problem while we spend time thinking about the real, elegant solution. And having two types like INTEGER and LONGINT without one being a subrange of the other seems like a kludge to me, however necessary it also appears. But let me ask a question. Is there ever any need for a Modula 3 compiler to implement a type like 0..1024 as more than 16 bits? Even if INTEGER is 32 bits? (I might have asked "more than 12 bits" in the above question, but modern 23-bit machines may very well have 16-bit operations but not 12-bit operations.) -- hendrik P.S. As far as I know, I don't think the C standard ever specifies that arithmetic operations on its file offset type (Is it offset_t? I forget.) have any relation whatsoever to actual file position? As far as I know, it could be a count of the number of bytes to read to reach that position, or it could consist of cylinder, track, and sector numbers, or it could even be encrypted. Fie on the C implementor that does any of these things, though. From hendrik at topoi.pooq.com Fri Jan 8 19:58:41 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 13:58:41 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: <4B468BD8.4020106@lcwb.coop> Message-ID: <20100108185841.GE14151@topoi.pooq.com> On Fri, Jan 08, 2010 at 11:26:07AM -0500, Tony Hosking wrote: > > The question really is what should the top type be? > > We don't want to have all ordinal types base themselves on LONGINT > because then they will all incur LONGINT operations (which may be more > expensive than the "natural" INTEGER operations). Is it even necessary for a compiler to implement -128..127 as more than one byte? -- hendrik From hendrik at topoi.pooq.com Fri Jan 8 20:04:09 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 14:04:09 -0500 Subject: [M3devel] Integers In-Reply-To: <4B476704.8010403@lcwb.coop> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> Message-ID: <20100108190409.GF14151@topoi.pooq.com> On Fri, Jan 08, 2010 at 11:10:28AM -0600, Rodney M. Bates wrote: > > What's unique about Modula-3 is that such representation changes are > left to the compiler, while the language merely views values as > sometimes belonging to more than one type, and allows such values to be > assigned when so. The usual approach in other languages is to elevate > the representation change from a machine-level matter to a language- > level matter by treating it as an implicit type change in addition to > a representation change. The result is always a lot of unnecessary > complexity in the language. ... ... > > > >Where in the language is it important that INTEGER and LONGINT be > >different base types? In other words, what advantages does this > >separation convey? > > One thing that is very much needed in a language (not the only thing) > is a type that always matches the implementation's native arithmetic > size, which is most efficient. If you don't distinguish this type, > it becomes either impossible or horribly convoluted to define arithmetic > so native machine arithmetic can be usually used where possible, > but multi-word arithmetic will be used where needed. Yes. You do need this type. And you can even call it INTEGER. But is there any reason it cannot be a predefined subrange type of LONGINT? -- hendrik From hosking at cs.purdue.edu Fri Jan 8 20:32:56 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 14:32:56 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100108185453.GD14151@topoi.pooq.com> References: <20100107131117.GA22266@topoi.pooq.com> <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> <2E21F50B-4710-4123-BB1F-FDF77CDB8C59@cs.purdue.edu> <20100108114448.3fukoteb40og04og@mail.elegosoft.com> <20100108185453.GD14151@topoi.pooq.com> Message-ID: <7743770A-2B7E-4AF7-8F6C-EC44041717AE@cs.purdue.edu> On 8 Jan 2010, at 13:54, hendrik at topoi.pooq.com wrote: > On Fri, Jan 08, 2010 at 11:44:48AM +0100, Olaf Wagner wrote: >> >> Just my opinion of course. I don't really understand why you are so >> drastically opposing LONGINT suddenly. Probably I haven't been able to >> follow some of the arguments. > > I could understand opposition to LONGINT if it were based on it being a > kludge stuck in to quickly patch a problem while we spend time thinking > about the real, elegant solution. And having two types like INTEGER and > LONGINT without one being a subrange of the other seems like a kludge to > me, however necessary it also appears. It really is kind of a kludge invented just for large files. > But let me ask a question. Is there ever any need for a Modula 3 > compiler to implement a type like 0..1024 as more than 16 bits? Even if > INTEGER is 32 bits? [0..1024] has memory representation of 16 bits. What's the point of the question? Values of [0..1024] are INTEGER and operations on them are INTEGER typed. > (I might have asked "more than 12 bits" in the above question, but > modern 23-bit machines may very well have 16-bit operations but not > 12-bit operations.) > > -- hendrik > > P.S. As far as I know, I don't think the C standard ever specifies that > arithmetic operations on its file offset type (Is it offset_t? I > forget.) have any relation whatsoever to actual file position? As far > as I know, it could be a count of the number of bytes to read to reach > that position, or it could consist of cylinder, track, and sector > numbers, or it could even be encrypted. Fie on the C implementor that > does any of these things, though. Right, so this argues in favor of a cleaner abstraction of file offsets rather than LONGINT. From hosking at cs.purdue.edu Fri Jan 8 20:33:54 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 14:33:54 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100108185841.GE14151@topoi.pooq.com> References: <4B468BD8.4020106@lcwb.coop> <20100108185841.GE14151@topoi.pooq.com> Message-ID: They are stored as 1-byte values. But the values of that type are INTEGERs and operated on as INTEGERs. On 8 Jan 2010, at 13:58, hendrik at topoi.pooq.com wrote: > On Fri, Jan 08, 2010 at 11:26:07AM -0500, Tony Hosking wrote: >> >> The question really is what should the top type be? >> >> We don't want to have all ordinal types base themselves on LONGINT >> because then they will all incur LONGINT operations (which may be more >> expensive than the "natural" INTEGER operations). > > Is it even necessary for a compiler to implement -128..127 as more than > one byte? > > -- hendrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Jan 8 20:36:18 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 14:36:18 -0500 Subject: [M3devel] Integers In-Reply-To: <20100108190409.GF14151@topoi.pooq.com> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> Message-ID: <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> On 8 Jan 2010, at 14:04, hendrik at topoi.pooq.com wrote: > On Fri, Jan 08, 2010 at 11:10:28AM -0600, Rodney M. Bates wrote: >> >> What's unique about Modula-3 is that such representation changes are >> left to the compiler, while the language merely views values as >> sometimes belonging to more than one type, and allows such values to be >> assigned when so. The usual approach in other languages is to elevate >> the representation change from a machine-level matter to a language- >> level matter by treating it as an implicit type change in addition to >> a representation change. The result is always a lot of unnecessary >> complexity in the language. > ... > ... >>> >>> Where in the language is it important that INTEGER and LONGINT be >>> different base types? In other words, what advantages does this >>> separation convey? >> >> One thing that is very much needed in a language (not the only thing) >> is a type that always matches the implementation's native arithmetic >> size, which is most efficient. If you don't distinguish this type, >> it becomes either impossible or horribly convoluted to define arithmetic >> so native machine arithmetic can be usually used where possible, >> but multi-word arithmetic will be used where needed. > > Yes. You do need this type. And you can even call it INTEGER. But is > there any reason it cannot be a predefined subrange type of LONGINT? I sense confusion here... INTEGER is not a subrange type. Neither is LONGINT. From rodney_bates at lcwb.coop Fri Jan 8 20:25:50 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 08 Jan 2010 13:25:50 -0600 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> References: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> Message-ID: <4B4786BE.3000607@lcwb.coop> Tony Hosking wrote: > Let's have a clean language proposal before thinking about implementing it... ;-) > > I continue to oppose mixing operations on both LONGINT and INTEGER. Just as one cannot mix REAL and LONGREAL. > I may accept checked assignability between INTEGER and LONGINT (after all, the bits are the same, its just a matter of how many are significant -- unlike REAL/LONGREAL/EXTENDED). > > Looking further at the assignability rules: > > A type T is assignable to a type U if: > > ? T <: U, or > ? U <: T and T is an array or a reference type other than ADDRESS (This restriction is lifted in unsafe modules.), or > ? T and U are ordinal types with at least one member in common. > > This suggests that we don't really need to say that INTEGER <: LONGINT. I once considered adding this subtype relation as a way of not requiring the ORD/VAL coding, but it has some additional other consequences that I considered undesirable. I don't remember what they were off the top of my head, but could no doubt reconstruct them, if anybody cares. > > We can simply rely on the third clause regarding their both being ordinal types with at least one member in common. Then assignment simply needs to test that the values are in range. Yes, this is exactly what I am saying. To require the ORD/VAL calls, we would have do one of: 1) Say LONGINT is not an ordinal type. 2) Say that 10 and 10L are not only expressions of different types, but also distinct values as well. The low values of LONGINT and the corresponding values of INTEGER would not be the same. 3) Alter the definition of assignability, for example to say in the third clause, that T and U must have the same base type as well as a member in common. Doing 1) Runs strongly against my intuitive sense of what "ordinal" means. It would also mean there would be no subranges of LONGINT and probably eliminate several other things you might expect to come along with LONGINT. Doing 2) Seems like a big contradiction to the way subranges work and the existing Modula-3 philosophy of types sometimes having overlapping value sets. Which leaves 3), which I think is the only reasonable way to do this. If we leave this as is, it will follow that assignment statements and mixed arithmetic are legal and work the same way as with different subranges of the same base type. Given the liberal assignability rules we already have, I don't think this is necessarily a bad idea, despite my general bias toward requiring more stuff to be explicit in code. There are about 8 or 9 places, as I recall, that would be affected because they require only assignability. The definitions of the arithmetic operators would have to be treated with some care to avoid allowing or requiring that INTEGER INTEGER be done in LONGINT machine arithmetic, something we absolutely must avoid. This points out where the analogy to subranges does not apply to INTEGER/LONGINT. With subranges, the only reasonable implementation is to expand the operands to the base type and do the arithmetic in that size. Here, we don't want that to happen unless at least one operand is LONGINT. On a side note, I do not believe the analogy to the floating types applies here. With INTEGER/LONGINT, there is a very obvious and natural equivalence between the values of INTEGER and the lower values of LONGINT. Not necessarily so with different native machine floating types. The messiness of floating representation means you can't assume the exactly representable reals are the same for two different floating types, even within some restricted value range. > > On 8 Jan 2010, at 02:44, Jay K wrote: > >> This simple diff in the front end allows the "obvious" mixing of INTEGER and LONGINT without any need for ORD or VAL. >> >> LONGINT + INTEGER => LONGINT >> LONGINT - INTEGER => LONGINT >> LONGINT * INTEGER => LONGINT >> LONGINT DIV INTEGER => LONGINT >> INTEGER DIV LONGINT => LONGINT (subtle and I think incorrect, should be INTEGER) >> INTEGER MOD LONGINT => INTEGER (subtle but I believe correct) >> LONGINT MOD INTEGER => INTEGER (subtle but I believe correct) >> MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be INTEGER) >> MAX(INTEGER, LONGINT) => LONGINT >> LONGINT := INTEGER >> >> Other mixes are less obvious and would require runtime checks. >> >> I think the backend will just work but I haven't tried that yet. >> (Truth be told, I can only affectively edit files on NT...) >> >> Thoughts? >> > From rodney_bates at lcwb.coop Fri Jan 8 20:33:37 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 08 Jan 2010 13:33:37 -0600 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <59DCA404-36FD-4EC0-B7AE-3FA59F3F6C4D@cs.purdue.edu> References: <20100107131117.GA22266@topoi.pooq.com> <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> <2E21F50B-4710-4123-BB1F-FDF77CDB8C59@cs.purdue.edu> <20100108114448.3fukoteb40og04og@mail.elegosoft.com> <59DCA404-36FD-4EC0-B7AE-3FA59F3F6C4D@cs.purdue.edu> Message-ID: <4B478891.8010101@lcwb.coop> Well I don't agree that large files sizes are the only reason to have LONGINT. They may be the specific case where this community has seen significant need. But I have a number of times in the past (in various programming languages) needed multi-word arithmetic. Moreover, new use cases will happen. Especially, we can expect the proliferation of embedded devices to create then. And I really believe it can be done without a lot of violence to the Language.. Tony Hosking wrote: > I am opposing LONGINT now (somewhat as a devil's advocate) because we introduced it simply to solve one very small problem: file sizes larger than INTEGER. Perhaps we would have been better off sticking with a double-INTEGER record with lo/hi fields to represent file sizes? > > Its introduction has added significant complication to the compiler, which I am frequently stumbling over (not to mention deep questions of typing in the language, as evidenced by the controversy over assignability between INTEGER and LONGINT). > > From rodney_bates at lcwb.coop Fri Jan 8 20:42:09 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Fri, 08 Jan 2010 13:42:09 -0600 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: <20100108173412.8531F1A207A@async.async.caltech.edu> References: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> <20100108173412.8531F1A207A@async.async.caltech.edu> Message-ID: <4B478A91.3090609@lcwb.coop> Mika Nystrom wrote: > Tony Hosking writes: > ... >> A type T is assignable to a type U if: >> >> =95 T <: U, or >> =95 U <: T and T is an array or a reference type other than = >> ADDRESS (This restriction is lifted in unsafe modules.), or >> =95 T and U are ordinal types with at least one member in = >> common. >> >> This suggests that we don't really need to say that INTEGER <: LONGINT. >> >> We can simply rely on the third clause regarding their both being = >> ordinal types with at least one member in common. Then assignment = >> simply needs to test that the values are in range. >> > > Are you sure about this for INTEGER and LONGINT? I.e., are 0 and 0L > the same "member"? > > By a similar argument, you could make REAL and LONGREAL assignable. > Are 0.0d0 and 0.0e0 the same "thing"? (On almost all machines they have > the same bit patterns, same as 0 and 0L for that matter, and I can add > that the way you do single-precision floating point on Alpha is by zeroing > a big chunk in the middle of your double-precision fp registers...) > > I think I am with you on removing LONGINT from the language. The proper > way of handling file sizes (or anything else that might be a bigger number > than a machine word) is through abstraction. I have a suspicion that it's > probably a severe micro-optimization to worry about the efficiency of > operations on file sizes. The thought that someone is adding automatic > type conversion to Modula-3, a la C, makes me feel slightly sick to > my stomach... I agree, I hate the horrible complexities of implicit type conversions in other languages. But this doesn't have to be done by automatic type conversion, just another instance of Modula-3's existing superior concept of assignability between non-disjoint types. > > I confess that my position is influenced by the fact that I have written > many programs that generate Modula-3 code as an "intermediate language". > I really really really need M3 to be easy to understand to get this to > work well. Also being able to parse interfaces and know precisely what > they mean is important to me. If the rules start getting sloppy.. that > would really upset me. On the other hand this means that if I'm faced > with a problem that doesn't really fit into M3 well, say, working in > arithmetic mod 2^(wordsize), my first instinct is not to demand changes > to the language definition but to write a code generator that takes > appropriate infix (or maybe more likely prefix) code and turns it into > the appropriate calls through the Word interface. It's a pain, yes, > but in the long run that's the right way, because you can do so much > more with that approach than just unsigned integers. > > Mika > In my original proposal, I said: ------------------------------------------------------------------------- This proposal satisfies (I believe) the following principles: The static correctness and type analysis of existing code written to the current language definition will not change with the new definition. This also implies that the new language definition will not introduce new type mismatches that would make existing pickles unreadable. The runtime semantics and time and space efficiency of existing code written to the current language definition will also not change with the new definition, if the native word size of the implementation does not change. Of course, porting existing code to an implementation with different native word size can change the runtime semantics by changing the supported value range, with or without language change. The static type analysis of programs written to the modified language definition will be independent of the implementation, particularly, of the native word size. This prevents inadvertently writing code that is highly nonportable among different native word sizes. The new, not-necessarily-native integer type does not extend to certain existing uses of INTEGER and CARDINAL that are of unlikely utility and would add complexity. ------------------------------------------------------------------------- I still believe we can do these things, and also that the changes to the language are not too drastic. They are mostly just more instances of existing concepts. From hosking at cs.purdue.edu Fri Jan 8 21:40:00 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 15:40:00 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <4B478891.8010101@lcwb.coop> References: <20100107131117.GA22266@topoi.pooq.com> <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> <2E21F50B-4710-4123-BB1F-FDF77CDB8C59@cs.purdue.edu> <20100108114448.3fukoteb40og04og@mail.elegosoft.com> <59DCA404-36FD-4EC0-B7AE-3FA59F3F6C4D@cs.purdue.edu> <4B478891.8010101@lcwb.coop> Message-ID: <597E64CD-7805-486C-AC7B-025A117C8B4E@cs.purdue.edu> But should we really introduce restricted range multi-word arithmetic? Why not instead make use of a general arbitrary range type like BigInteger.T? (see the arithmetic package) Again, I am acting devil's advocate here... On 8 Jan 2010, at 14:33, Rodney M. Bates wrote: > Well I don't agree that large files sizes are the only reason to have LONGINT. They may be the > specific case where this community has seen significant need. But I have a number of times > in the past (in various programming languages) needed multi-word arithmetic. Moreover, > new use cases will happen. Especially, we can expect the proliferation of embedded devices > to create then. And I really believe it can be done without a lot of violence to the > Language.. > > Tony Hosking wrote: >> I am opposing LONGINT now (somewhat as a devil's advocate) because we introduced it simply to solve one very small problem: file sizes larger than INTEGER. Perhaps we would have been better off sticking with a double-INTEGER record with lo/hi fields to represent file sizes? >> Its introduction has added significant complication to the compiler, which I am frequently stumbling over (not to mention deep questions of typing in the language, as evidenced by the controversy over assignability between INTEGER and LONGINT). >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Fri Jan 8 21:47:56 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 15:47:56 -0500 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: <4B4786BE.3000607@lcwb.coop> References: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> <4B4786BE.3000607@lcwb.coop> Message-ID: <93B01681-30DB-4D5E-9429-131DCB74E794@cs.purdue.edu> On 8 Jan 2010, at 14:25, Rodney M. Bates wrote: > > > Tony Hosking wrote: >> Let's have a clean language proposal before thinking about implementing it... ;-) >> I continue to oppose mixing operations on both LONGINT and INTEGER. Just as one cannot mix REAL and LONGREAL. >> I may accept checked assignability between INTEGER and LONGINT (after all, the bits are the same, its just a matter of how many are significant -- unlike REAL/LONGREAL/EXTENDED). >> Looking further at the assignability rules: >> A type T is assignable to a type U if: >> ? T <: U, or >> ? U <: T and T is an array or a reference type other than ADDRESS (This restriction is lifted in unsafe modules.), or >> ? T and U are ordinal types with at least one member in common. >> This suggests that we don't really need to say that INTEGER <: LONGINT. > > I once considered adding this subtype relation as a way of not requiring the ORD/VAL coding, > but it has some additional other consequences that I considered undesirable. I don't > remember what they were off the top of my head, but could no doubt reconstruct them, > if anybody cares. Right, I much prefer assignability rule 3, rather than a subtype relationship. >> We can simply rely on the third clause regarding their both being ordinal types with at least one member in common. Then assignment simply needs to test that the values are in range. > > Yes, this is exactly what I am saying. To require the ORD/VAL calls, we would have > do one of: > > 1) Say LONGINT is not an ordinal type. Not necessarily. See my definition of ORD/VAL in the update language spec. > 2) Say that 10 and 10L are not only expressions of different types, but > also distinct values as well. The low values of LONGINT and the > corresponding values of INTEGER would not be the same. I don't think we need to say they are different values (in fact, they can be converted). VAL(10, LONGINT) = 10L. > 3) Alter the definition of assignability, for example to say in the third clause, > that T and U must have the same base type as well as a member in common. In my definition both INTEGER and LONGINT *are* ordinal types so no need to change. > Doing 1) Runs strongly against my intuitive sense of what "ordinal" means. It would > also mean there would be no subranges of LONGINT and probably eliminate several > other things you might expect to come along with LONGINT. Agreed. > Doing 2) Seems like a big contradiction to the way subranges work and the existing > Modula-3 philosophy of types sometimes having overlapping value sets. Agreed. > Which leaves 3), which I think is the only reasonable way to do this. I don't see the need if both are ordinal types. They have some values in common. So they are assignable. > If we leave this as is, it will follow that assignment statements and mixed arithmetic > are legal and work the same way as with different subranges of the same base type. > Given the liberal assignability rules we already have, I don't think this is > necessarily a bad idea, despite my general bias toward requiring more stuff to > be explicit in code. There are about 8 or 9 places, as I recall, that would be > affected because they require only assignability. So, in the current implementation we just don't have assignability and mixed arithmetic. > The definitions of the arithmetic operators would have to be treated with some care > to avoid allowing or requiring that INTEGER INTEGER be done in LONGINT machine > arithmetic, something we absolutely must avoid. Correct. > This points out where the analogy > to subranges does not apply to INTEGER/LONGINT. With subranges, the only reasonable > implementation is to expand the operands to the base type and do the arithmetic > in that size. But that is exactly how the current implementation works. > Here, we don't want that to happen unless at least one operand is > LONGINT. So, the base type yields the correct behavior. > On a side note, I do not believe the analogy to the floating types applies here. > With INTEGER/LONGINT, there is a very obvious and natural equivalence between > the values of INTEGER and the lower values of LONGINT. Not necessarily so with > different native machine floating types. The messiness of floating representation > means you can't assume the exactly representable reals are the same for two different > floating types, even within some restricted value range. Yes, that is why I am leaning in your direction: assignability plus mixed arithmetic. > > > >> On 8 Jan 2010, at 02:44, Jay K wrote: >>> This simple diff in the front end allows the "obvious" mixing of INTEGER and LONGINT without any need for ORD or VAL. >>> LONGINT + INTEGER => LONGINT LONGINT - INTEGER => LONGINT LONGINT * INTEGER => LONGINT LONGINT DIV INTEGER => LONGINT INTEGER DIV LONGINT => LONGINT (subtle and I think incorrect, should be INTEGER) INTEGER MOD LONGINT => INTEGER (subtle but I believe correct) LONGINT MOD INTEGER => INTEGER (subtle but I believe correct) MIN(INTEGER, LONGINT) => LONGINT (This is wrong actually, should be INTEGER) MAX(INTEGER, LONGINT) => LONGINT LONGINT := INTEGER Other mixes are less obvious and would require runtime checks. >>> I think the backend will just work but I haven't tried that yet. >>> (Truth be told, I can only affectively edit files on NT...) >>> Thoughts? >>> >> From hosking at cs.purdue.edu Fri Jan 8 21:51:13 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 15:51:13 -0500 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: <4B478A91.3090609@lcwb.coop> References: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu> <20100108173412.8531F1A207A@async.async.caltech.edu> <4B478A91.3090609@lcwb.coop> Message-ID: <35FA329C-9EF2-4325-8C1E-CA45F88D930F@cs.purdue.edu> Once more summarising the discussion so far. *If* we accept that LONGINT should stay then I agree we should implement Rodney's proposal (the current implementation + assignability between INTEGER and LONGINT + mixed arithmetic). The question remains: is LONGINT necessary or simply a kludge better satisfied by arbitrary precision arithmetic like BigInteger.T? On 8 Jan 2010, at 14:42, Rodney M. Bates wrote: > > > Mika Nystrom wrote: >> Tony Hosking writes: >> ... >>> A type T is assignable to a type U if: >>> >>> =95 T <: U, or >>> =95 U <: T and T is an array or a reference type other than = >>> ADDRESS (This restriction is lifted in unsafe modules.), or >>> =95 T and U are ordinal types with at least one member in = >>> common. >>> >>> This suggests that we don't really need to say that INTEGER <: LONGINT. >>> >>> We can simply rely on the third clause regarding their both being = >>> ordinal types with at least one member in common. Then assignment = >>> simply needs to test that the values are in range. >>> >> Are you sure about this for INTEGER and LONGINT? I.e., are 0 and 0L >> the same "member"? >> By a similar argument, you could make REAL and LONGREAL assignable. >> Are 0.0d0 and 0.0e0 the same "thing"? (On almost all machines they have >> the same bit patterns, same as 0 and 0L for that matter, and I can add >> that the way you do single-precision floating point on Alpha is by zeroing >> a big chunk in the middle of your double-precision fp registers...) >> I think I am with you on removing LONGINT from the language. The proper >> way of handling file sizes (or anything else that might be a bigger number >> than a machine word) is through abstraction. I have a suspicion that it's >> probably a severe micro-optimization to worry about the efficiency of >> operations on file sizes. The thought that someone is adding automatic >> type conversion to Modula-3, a la C, makes me feel slightly sick to >> my stomach... > > I agree, I hate the horrible complexities of implicit type conversions > in other languages. But this doesn't have to be done by automatic type > conversion, just another instance of Modula-3's existing superior concept of > assignability between non-disjoint types. > >> I confess that my position is influenced by the fact that I have written >> many programs that generate Modula-3 code as an "intermediate language". >> I really really really need M3 to be easy to understand to get this to >> work well. Also being able to parse interfaces and know precisely what >> they mean is important to me. If the rules start getting sloppy.. that >> would really upset me. On the other hand this means that if I'm faced >> with a problem that doesn't really fit into M3 well, say, working in >> arithmetic mod 2^(wordsize), my first instinct is not to demand changes >> to the language definition but to write a code generator that takes >> appropriate infix (or maybe more likely prefix) code and turns it into >> the appropriate calls through the Word interface. It's a pain, yes, but in the long run that's the right way, because you can do so much >> more with that approach than just unsigned integers. >> Mika > > In my original proposal, I said: > ------------------------------------------------------------------------- > This proposal satisfies (I believe) the following principles: > > The static correctness and type analysis of existing code written to > the current language definition will not change with the new > definition. This also implies that the new language definition will > not introduce new type mismatches that would make existing pickles > unreadable. > > The runtime semantics and time and space efficiency of existing code > written to the current language definition will also not change with > the new definition, if the native word size of the implementation does > not change. Of course, porting existing code to an implementation > with different native word size can change the runtime semantics by > changing the supported value range, with or without language change. > > The static type analysis of programs written to the modified language > definition will be independent of the implementation, particularly, of > the native word size. This prevents inadvertently writing code that > is highly nonportable among different native word sizes. > > The new, not-necessarily-native integer type does not extend to > certain existing uses of INTEGER and CARDINAL that are of unlikely > utility and would add complexity. > > > ------------------------------------------------------------------------- > > I still believe we can do these things, and also that the changes > to the language are not too drastic. They are mostly just more > instances of existing concepts. From hendrik at topoi.pooq.com Fri Jan 8 22:39:23 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 16:39:23 -0500 Subject: [M3devel] Integers In-Reply-To: <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> Message-ID: <20100108213923.GA9749@topoi.pooq.com> On Fri, Jan 08, 2010 at 02:36:18PM -0500, Tony Hosking wrote: > On 8 Jan 2010, at 14:04, hendrik at topoi.pooq.com wrote: > > > On Fri, Jan 08, 2010 at 11:10:28AM -0600, Rodney M. Bates wrote: > >> > >> What's unique about Modula-3 is that such representation changes are > >> left to the compiler, while the language merely views values as > >> sometimes belonging to more than one type, and allows such values to be > >> assigned when so. The usual approach in other languages is to elevate > >> the representation change from a machine-level matter to a language- > >> level matter by treating it as an implicit type change in addition to > >> a representation change. The result is always a lot of unnecessary > >> complexity in the language. > > ... > > ... > >>> > >>> Where in the language is it important that INTEGER and LONGINT be > >>> different base types? In other words, what advantages does this > >>> separation convey? > >> > >> One thing that is very much needed in a language (not the only thing) > >> is a type that always matches the implementation's native arithmetic > >> size, which is most efficient. If you don't distinguish this type, > >> it becomes either impossible or horribly convoluted to define arithmetic > >> so native machine arithmetic can be usually used where possible, > >> but multi-word arithmetic will be used where needed. > > > > Yes. You do need this type. And you can even call it INTEGER. But is > > there any reason it cannot be a predefined subrange type of LONGINT? > > I sense confusion here... > > INTEGER is not a subrange type. The question is not whether it is a subrange type. It isn't. The question is whether it could be. > Neither is LONGINT. > -- hendrik From hosking at cs.purdue.edu Fri Jan 8 22:47:00 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 16:47:00 -0500 Subject: [M3devel] Integers In-Reply-To: <20100108213923.GA9749@topoi.pooq.com> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> Message-ID: <889CD037-4BB0-47E7-B346-72C87C42A0AB@cs.purdue.edu> On 8 Jan 2010, at 16:39, hendrik at topoi.pooq.com wrote: >> I sense confusion here... >> >> INTEGER is not a subrange type. > > The question is not whether it is a subrange type. It isn't. > The question is whether it could be. I think that would result in major contradictions in the type system. From mika at async.async.caltech.edu Fri Jan 8 22:50:28 2010 From: mika at async.async.caltech.edu (Mika Nystrom) Date: Fri, 08 Jan 2010 13:50:28 -0800 Subject: [M3devel] Integers In-Reply-To: <20100108213923.GA9749@topoi.pooq.com> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> Message-ID: <20100108215028.40A651A207A@async.async.caltech.edu> Hendrik, do you mean: "INTEGER is that subrange of LONGINT that happens to be efficiently implementable on the target architecture"? Why choose a specific size (e.g., 64 bits) for LONGINT, then? Can I choose it as I please when I configure/compile the compiler? Mika hendrik at topoi.pooq.com writes: >On Fri, Jan 08, 2010 at 02:36:18PM -0500, Tony Hosking wrote: >> On 8 Jan 2010, at 14:04, hendrik at topoi.pooq.com wrote: >> >> > On Fri, Jan 08, 2010 at 11:10:28AM -0600, Rodney M. Bates wrote: >> >> >> >> What's unique about Modula-3 is that such representation changes are >> >> left to the compiler, while the language merely views values as >> >> sometimes belonging to more than one type, and allows such values to be >> >> assigned when so. The usual approach in other languages is to elevate >> >> the representation change from a machine-level matter to a language- >> >> level matter by treating it as an implicit type change in addition to >> >> a representation change. The result is always a lot of unnecessary >> >> complexity in the language. >> > ... >> > ... >> >>> >> >>> Where in the language is it important that INTEGER and LONGINT be >> >>> different base types? In other words, what advantages does this >> >>> separation convey? >> >> >> >> One thing that is very much needed in a language (not the only thing) >> >> is a type that always matches the implementation's native arithmetic >> >> size, which is most efficient. If you don't distinguish this type, >> >> it becomes either impossible or horribly convoluted to define arithmetic >> >> so native machine arithmetic can be usually used where possible, >> >> but multi-word arithmetic will be used where needed. >> > >> > Yes. You do need this type. And you can even call it INTEGER. But is >> > there any reason it cannot be a predefined subrange type of LONGINT? >> >> I sense confusion here... >> >> INTEGER is not a subrange type. > >The question is not whether it is a subrange type. It isn't. >The question is whether it could be. > >> Neither is LONGINT. >> > >-- hendrik From hendrik at topoi.pooq.com Fri Jan 8 22:50:33 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 16:50:33 -0500 Subject: [M3devel] Integers In-Reply-To: <889CD037-4BB0-47E7-B346-72C87C42A0AB@cs.purdue.edu> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <889CD037-4BB0-47E7-B346-72C87C42A0AB@cs.purdue.edu> Message-ID: <20100108215033.GB9749@topoi.pooq.com> On Fri, Jan 08, 2010 at 04:47:00PM -0500, Tony Hosking wrote: > On 8 Jan 2010, at 16:39, hendrik at topoi.pooq.com wrote: > >> I sense confusion here... > >> > >> INTEGER is not a subrange type. > > > > The question is not whether it is a subrange type. It isn't. > > The question is whether it could be. > > I think that would result in major contradictions in the type system. Just what would the malign consequences be? -- hendrik From hosking at cs.purdue.edu Fri Jan 8 22:53:29 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 16:53:29 -0500 Subject: [M3devel] Integers In-Reply-To: <20100108215033.GB9749@topoi.pooq.com> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <889CD037-4BB0-47E7-B346-72C87C42A0AB@cs.purdue.edu> <20100108215033.GB9749@topoi.pooq.com> Message-ID: <7A00A010-D0C2-42C0-84ED-52B849A50F7A@cs.purdue.edu> Then the base type of INTEGER would be LONGINT. Thus, INTEGER operations would incur the expense of unnatural LONGINT operations. That is unacceptable. On 8 Jan 2010, at 16:50, hendrik at topoi.pooq.com wrote: > On Fri, Jan 08, 2010 at 04:47:00PM -0500, Tony Hosking wrote: >> On 8 Jan 2010, at 16:39, hendrik at topoi.pooq.com wrote: >>>> I sense confusion here... >>>> >>>> INTEGER is not a subrange type. >>> >>> The question is not whether it is a subrange type. It isn't. >>> The question is whether it could be. >> >> I think that would result in major contradictions in the type system. > > Just what would the malign consequences be? > > -- hendrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Fri Jan 8 23:30:57 2010 From: jay.krell at cornell.edu (Jay K) Date: Fri, 8 Jan 2010 22:30:57 +0000 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: <35FA329C-9EF2-4325-8C1E-CA45F88D930F@cs.purdue.edu> References: <8E59C253-6AE7-4A5B-82B3-11DB7360FE2E@cs.purdue.edu>, <20100108173412.8531F1A207A@async.async.caltech.edu>, <4B478A91.3090609@lcwb.coop>, <35FA329C-9EF2-4325-8C1E-CA45F88D930F@cs.purdue.edu> Message-ID: > The question remains: is LONGINT necessary or simply a kludge better satisfied by arbitrary precision arithmetic like BigInteger.T? Two of us addressed this. The answer is not technically/scientifically pleasing. The answer is simply that in-fix operators are more convenient and libraries are not. Obviously the general clean answer is either: operator overloading on user defined types, making the library convenient or maybe a language feature for fixed but arbitrary precision integers e.g. int1024 = BITS 1024 for INTEGER or uint1024 = BITS 1024 for [0..Word.LShift(1, 1024)] or uint1024 = [0..Word.LShift(1, 1024)] and the compiler would be compelled to generate code for any precision. These are both more work. LONGINT is indeed a special case. C compilers all provide it "long long" or "__int64". File sizes are indeed probably the typical use case for C? But also things like InterlockedCompareExchange64 of some "packed" format. Personally I would gladly accept FileSize = [0..Word.LShift(1, 63 or 64)]; even so...the compiler/language feature could (initially) limit the "bits" to 64, but still implement via this more general syntax and not some new special type/keyword. This is the question floating around: maybe there are just integers of varying size/range. Maybe the compiler can notice if the size is <= or > a natural size? Mixed arithmetic would be possible among arbitrary pairs of sizes and have a simple formula for the result. Assuming "silent wraparound", addition would just pick the larger of the two. But then, what if I assign to an even larger type? Hm. Then you want addition of n and m to produce max(n, m) + 1, and such. Perhaps there is some rule..you know..checked narrowing..? And the checks can be omitted if the assignment is to a larger type? e.g. LONGINT := INTEGER + INTEGER => no overflow check LONGINT := LONGINT + LONGINT => overflow check int1024 := LONGINT + LONGINT => no overflow check ? In reality I think no code would use the wider := narrow + narrow. But it seems technically reasonable. In reality code either wants the overflow check, or a type that expands its precision as needed. ("bignum", etc.) - Jay > From: hosking at cs.purdue.edu > Date: Fri, 8 Jan 2010 15:51:13 -0500 > To: rodney_bates at lcwb.coop > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] mixing INTEGER and LONGINT? > > Once more summarising the discussion so far. > > *If* we accept that LONGINT should stay then I agree we should implement Rodney's proposal (the current implementation + assignability between INTEGER and LONGINT + mixed arithmetic). > > The question remains: is LONGINT necessary or simply a kludge better satisfied by arbitrary precision arithmetic like BigInteger.T? > > On 8 Jan 2010, at 14:42, Rodney M. Bates wrote: > > > > > > > Mika Nystrom wrote: > >> Tony Hosking writes: > >> ... > >>> A type T is assignable to a type U if: > >>> > >>> =95 T <: U, or > >>> =95 U <: T and T is an array or a reference type other than = > >>> ADDRESS (This restriction is lifted in unsafe modules.), or > >>> =95 T and U are ordinal types with at least one member in = > >>> common. > >>> > >>> This suggests that we don't really need to say that INTEGER <: LONGINT. > >>> > >>> We can simply rely on the third clause regarding their both being = > >>> ordinal types with at least one member in common. Then assignment = > >>> simply needs to test that the values are in range. > >>> > >> Are you sure about this for INTEGER and LONGINT? I.e., are 0 and 0L > >> the same "member"? > >> By a similar argument, you could make REAL and LONGREAL assignable. > >> Are 0.0d0 and 0.0e0 the same "thing"? (On almost all machines they have > >> the same bit patterns, same as 0 and 0L for that matter, and I can add > >> that the way you do single-precision floating point on Alpha is by zeroing > >> a big chunk in the middle of your double-precision fp registers...) > >> I think I am with you on removing LONGINT from the language. The proper > >> way of handling file sizes (or anything else that might be a bigger number > >> than a machine word) is through abstraction. I have a suspicion that it's > >> probably a severe micro-optimization to worry about the efficiency of > >> operations on file sizes. The thought that someone is adding automatic > >> type conversion to Modula-3, a la C, makes me feel slightly sick to > >> my stomach... > > > > I agree, I hate the horrible complexities of implicit type conversions > > in other languages. But this doesn't have to be done by automatic type > > conversion, just another instance of Modula-3's existing superior concept of > > assignability between non-disjoint types. > > > >> I confess that my position is influenced by the fact that I have written > >> many programs that generate Modula-3 code as an "intermediate language". > >> I really really really need M3 to be easy to understand to get this to > >> work well. Also being able to parse interfaces and know precisely what > >> they mean is important to me. If the rules start getting sloppy.. that > >> would really upset me. On the other hand this means that if I'm faced > >> with a problem that doesn't really fit into M3 well, say, working in > >> arithmetic mod 2^(wordsize), my first instinct is not to demand changes > >> to the language definition but to write a code generator that takes > >> appropriate infix (or maybe more likely prefix) code and turns it into > >> the appropriate calls through the Word interface. It's a pain, yes, but in the long run that's the right way, because you can do so much > >> more with that approach than just unsigned integers. > >> Mika > > > > In my original proposal, I said: > > ------------------------------------------------------------------------- > > This proposal satisfies (I believe) the following principles: > > > > The static correctness and type analysis of existing code written to > > the current language definition will not change with the new > > definition. This also implies that the new language definition will > > not introduce new type mismatches that would make existing pickles > > unreadable. > > > > The runtime semantics and time and space efficiency of existing code > > written to the current language definition will also not change with > > the new definition, if the native word size of the implementation does > > not change. Of course, porting existing code to an implementation > > with different native word size can change the runtime semantics by > > changing the supported value range, with or without language change. > > > > The static type analysis of programs written to the modified language > > definition will be independent of the implementation, particularly, of > > the native word size. This prevents inadvertently writing code that > > is highly nonportable among different native word sizes. > > > > The new, not-necessarily-native integer type does not extend to > > certain existing uses of INTEGER and CARDINAL that are of unlikely > > utility and would add complexity. > > > > > > ------------------------------------------------------------------------- > > > > I still believe we can do these things, and also that the changes > > to the language are not too drastic. They are mostly just more > > instances of existing concepts. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hendrik at topoi.pooq.com Sat Jan 9 00:05:05 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 18:05:05 -0500 Subject: [M3devel] Unbounded but finite LONGINT (was: Re: Integers In-Reply-To: <20100108215028.40A651A207A@async.async.caltech.edu> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <20100108215028.40A651A207A@async.async.caltech.edu> Message-ID: <20100108230505.GC9749@topoi.pooq.com> On Fri, Jan 08, 2010 at 01:50:28PM -0800, Mika Nystrom wrote: > > Hendrik, do you mean: > > "INTEGER is that subrange of LONGINT that happens to be efficiently > implementable on the target architecture"? > > Why choose a specific size (e.g., 64 bits) for LONGINT, then? Can I > choose it as I please when I configure/compile the compiler? > > Mika I've just been thinking of that. Why even have a size for LONGINT? Why not allow the programmer to use only subranges of LONGINT? The arithmetic operations all have the property that you can compute subranges for the reults given subranges for the operands. So intermediate results are all bounded in size, you can compute without overflow happening ... until you get to narrow the final result for assignment to whatever variable you want to assign it to. I suspect there are compiler optimisations (well, let's ne honest, call them ameliorations) that could be performed to move the final range-truncate-check backward through the series of operations and limit the number of unnecessary bits that have been computed. These ameliorations are likely to be more effective if no range check need be performed on final assignment (but there's always a conflict between amelioration and run-time checks, isn't there?) We could do this for LONGINT completely independent of whatever we do with INTEGER. INTEGER doesn't need to be a subrange of LONGINT. INTEGER is what you use when you particularly want to use machine-efficient data and operations. LONGINT is what you use when that's not enough, and you want to statically specify the size of integer you need, and pay the price. What with machines having carry and overflow flags, add-with-carry instructions, it chould be possible to generate reasonably efficient code anyway, without the full overhead of run-time-determined number sizes. Most machines already have integer multiply instructions that return a double-length product. It's such a pity to waste them. -- hendrik From hendrik at topoi.pooq.com Sat Jan 9 00:11:54 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 18:11:54 -0500 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: References: <35FA329C-9EF2-4325-8C1E-CA45F88D930F@cs.purdue.edu> Message-ID: <20100108231154.GD9749@topoi.pooq.com> On Fri, Jan 08, 2010 at 10:30:57PM +0000, Jay K wrote: > > > The question remains: is LONGINT necessary or simply a kludge > > better satisfied by arbitrary precision arithmetic like > > BigInteger.T? > > > Two of us addressed this. > > The answer is not technically/scientifically pleasing. > The answer is simply that in-fix operators are more convenient and > libraries are not. > > Obviously the general clean answer is either: > > operator overloading on user defined types, making the library convenient > > or maybe a language feature for fixed but arbitrary precision integers Why not make LONGINT the base type for all these fixed but arbitrary precision integers. But don't allow anyone to declare a variable of type LONGINT, so we never have to specify a size for it, and its subranges can be as large as anyone pleases. > e.g. e.g. > > > int1024 = BITS 1024 for INTEGER int1024 = BITS 1024 for LONGINT > or uint1024 = BITS 1024 for [0..Word.LShift(1, 1024)] or uint1024 = BITS 1024 for [0..Word.LShift(1L, 1024)] > > or uint1024 = [0..Word.LShift(1, 1024)] or uint1024 = [0..Word.LShift(1L, 1024)] > > and the compiler would be compelled to generate code for any precision. > > These are both more work. > > LONGINT is indeed a special case. But if we let it be finite but unbounded it's a rather different special case. -- hendrik From hosking at cs.purdue.edu Sat Jan 9 01:53:07 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 19:53:07 -0500 Subject: [M3devel] Unbounded but finite LONGINT (was: Re: Integers In-Reply-To: <20100108230505.GC9749@topoi.pooq.com> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <20100108215028.40A651A207A@async.async.caltech.edu> <20100108230505.GC9749@topoi.pooq.com> Message-ID: I think what you are advocating is Rodney's proposal + assignability of INTEGER and LONGINT + mixed arithmetic. On 8 Jan 2010, at 18:05, hendrik at topoi.pooq.com wrote: > On Fri, Jan 08, 2010 at 01:50:28PM -0800, Mika Nystrom wrote: >> >> Hendrik, do you mean: >> >> "INTEGER is that subrange of LONGINT that happens to be efficiently >> implementable on the target architecture"? >> >> Why choose a specific size (e.g., 64 bits) for LONGINT, then? Can I >> choose it as I please when I configure/compile the compiler? >> >> Mika > > I've just been thinking of that. Why even have a size for LONGINT? Why > not allow the programmer to use only subranges of LONGINT? The > arithmetic operations all have the property that you can compute > subranges for the reults given subranges for the operands. So > intermediate results are all bounded in size, you can compute without > overflow happening ... until you get to narrow the final result for > assignment to whatever variable you want to > assign it to. > > I suspect there are compiler optimisations (well, let's ne honest, > call them ameliorations) that could be performed to move the final > range-truncate-check backward through the series of operations and limit > the number of unnecessary bits that have been computed. These > ameliorations are likely to be more effective if no range check need be > performed on final assignment (but there's always a conflict between > amelioration and run-time checks, isn't there?) > > We could do this for LONGINT completely independent of whatever we do > with INTEGER. INTEGER doesn't need to be a subrange of LONGINT. > INTEGER is what you use when you particularly want to use > machine-efficient data and operations. LONGINT is what you use when > that's not enough, and you want to statically specify the size of > integer you need, and pay the price. What with machines having carry > and overflow flags, add-with-carry instructions, it chould be possible > to generate reasonably efficient code anyway, without the full overhead > of run-time-determined number sizes. > > Most machines already have integer multiply instructions that return a > double-length product. It's such a pity to waste them. > > -- hendrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From hendrik at topoi.pooq.com Sat Jan 9 02:33:42 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 20:33:42 -0500 Subject: [M3devel] Unbounded but finite LONGINT (was: Re: Integers In-Reply-To: References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <20100108215028.40A651A207A@async.async.caltech.edu> <20100108230505.GC9749@topoi.pooq.com> Message-ID: <20100109013342.GA23519@topoi.pooq.com> On Fri, Jan 08, 2010 at 07:53:07PM -0500, Tony Hosking wrote: > I think what you are advocating is Rodney's proposal + assignability > of INTEGER and LONGINT + mixed arithmetic. I thought Rodney's propsal still had the compiler impose a bound on the size of LONGINT. Or did I miss something? I'm proposing to let the programmer use subranges of LONGINT that are as long as he wishes. And if the computer runs out of virtual memory to store one of the programmer's long integers, well, that's the computer imposing the limit, not the language. -- hendrik From hendrik at topoi.pooq.com Sat Jan 9 02:40:31 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 20:40:31 -0500 Subject: [M3devel] Integers In-Reply-To: <7A00A010-D0C2-42C0-84ED-52B849A50F7A@cs.purdue.edu> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <889CD037-4BB0-47E7-B346-72C87C42A0AB@cs.purdue.edu> <20100108215033.GB9749@topoi.pooq.com> <7A00A010-D0C2-42C0-84ED-52B849A50F7A@cs.purdue.edu> Message-ID: <20100109014030.GB23519@topoi.pooq.com> On Fri, Jan 08, 2010 at 04:53:29PM -0500, Tony Hosking wrote: > Then the base type of INTEGER would be LONGINT. > > Thus, INTEGER operations would incur the expense of unnatural LONGINT > operations. I get it. It's not a matter of the size of the INTEGERs; it's a matter of the operations on them -- that operations on INTEGERs are limited to whatever size the computer processes efficiently, and that this limit is *checked* (at least in principle) for reliability. -- hendrik > > That is unacceptable. From hendrik at topoi.pooq.com Sat Jan 9 02:44:37 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 20:44:37 -0500 Subject: [M3devel] Unbounded but finite LONGINT (was: Re: Integers In-Reply-To: <20100109013342.GA23519@topoi.pooq.com> References: <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <20100108215028.40A651A207A@async.async.caltech.edu> <20100108230505.GC9749@topoi.pooq.com> <20100109013342.GA23519@topoi.pooq.com> Message-ID: <20100109014437.GC23519@topoi.pooq.com> On Fri, Jan 08, 2010 at 08:33:42PM -0500, hendrik at topoi.pooq.com wrote: > On Fri, Jan 08, 2010 at 07:53:07PM -0500, Tony Hosking wrote: > > I think what you are advocating is Rodney's proposal + assignability > > of INTEGER and LONGINT + mixed arithmetic. > > I thought Rodney's propsal still had the compiler impose a bound on the > size of LONGINT. Or did I miss something? In particular, I would have there be no FIRST(LONGINT) or LAST(LONGINT). -- hendrik > > I'm proposing to let the programmer use subranges of LONGINT that are as > long as he wishes. And if the computer runs out of virtual memory to > store one of the programmer's long integers, well, that's the computer > imposing the limit, not the language. From jay.krell at cornell.edu Sat Jan 9 03:09:13 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 02:09:13 +0000 Subject: [M3devel] Unbounded but finite LONGINT (was: Re: Integers In-Reply-To: <20100109014437.GC23519@topoi.pooq.com> References: <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu>, <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop>, <20100108190409.GF14151@topoi.pooq.com>, <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu>, <20100108213923.GA9749@topoi.pooq.com>, <20100108215028.40A651A207A@async.async.caltech.edu>, <20100108230505.GC9749@topoi.pooq.com>, , <20100109013342.GA23519@topoi.pooq.com>, <20100109014437.GC23519@topoi.pooq.com> Message-ID: I hear Hendrik proposing that "LONGINT" is the name for fixed arbitrary precision integers. That it might even have a name. Or the user has to mention it in order to acknowledge he is using something potentially inefficient. FileSize = BITS 64 FOR LONGINT; FileSize = [1..LongInt.LShift(1, 63)]; FileSize = LONGINT[64]; or such This is not a bad idea. I think the "real" problem here is a multitude of options/scenarios and a lack of vocabulary. As I said, there is a time/place for "silent wraparound", for trapping overflow, for extending precision to fit. Also I'm surprised you can't mix REAL and LONGREAL. Also I don't think INTEGER + LONGINT is all that confusing or, as I said, subtle. It isn't /immediately/ obvious how to deal with MIN, MAX, MOD, DIV, but it is still not that tricky. MIN(INTEGER, LONGINT) is INTEGER. Not that difficult to figure out why. At least one of the inputs fits in an integer and the result is the smaller input. MAX(INTEGER, LONGINT) is LONGINT, ditto. One of the inputs might not fit in an INTEGER and the result is the larger input. INTEGER DIV LONGINT is INTEGER BIG DIV SMALL1 is SMALL2 SMALL DIV BIG is 0 remainder SMALL. LONGINT DIV INTEGER is LONGINT Prove with one simple case: BIG1 DIV 2 is BIG2. Easier BIG1 DIV 1 is BIG1. Consider: LONGINT MOD INTEGER and INTEGER MOD LONGINT SMALL divided by BIG is, again, 0 remainder SMALL, INTEGER BIG divided by SMALL1 is SMALL2, remainder [0..SMALL1 - 1] which is INTEGER. That is, division either gives you 0 and remainder = first number. Or it gives you non-zero and remainder is less than the second number. 50 divided by 100 is 0 remainder 50. 109 divided by 10 is 10 remainder 9 FOR loops also should allow mixing. - Jay > Date: Fri, 8 Jan 2010 20:44:37 -0500 > From: hendrik at topoi.pooq.com > To: m3devel at elegosoft.com > Subject: Re: [M3devel] Unbounded but finite LONGINT (was: Re: Integers > > On Fri, Jan 08, 2010 at 08:33:42PM -0500, hendrik at topoi.pooq.com wrote: > > On Fri, Jan 08, 2010 at 07:53:07PM -0500, Tony Hosking wrote: > > > I think what you are advocating is Rodney's proposal + assignability > > > of INTEGER and LONGINT + mixed arithmetic. > > > > I thought Rodney's propsal still had the compiler impose a bound on the > > size of LONGINT. Or did I miss something? > > In particular, I would have there be no FIRST(LONGINT) or LAST(LONGINT). > > -- hendrik > > > > I'm proposing to let the programmer use subranges of LONGINT that are as > > long as he wishes. And if the computer runs out of virtual memory to > > store one of the programmer's long integers, well, that's the computer > > imposing the limit, not the language. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Jan 9 03:16:57 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 02:16:57 +0000 Subject: [M3devel] still need a branch for longint changes? Message-ID: Still need a branch for longint changes? I doubt what I have is where we are going, though it is a step toward it. Just wait for Tony to implement Rodney's proposal? Or I work on it in a branch? It doesn't look too difficult to at least mostly do. I already have "mixed" stuff compiling and assignability INTEGER to LONGINT. I didn't yet do anything requiring runtime checks, but it's not that hard to do, given that there are already checks for assignment involving only partly overlapping ranges. Or maybe just take my stuff to the mainline and then refine/reduce it later? - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 9 03:23:15 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 21:23:15 -0500 Subject: [M3devel] still need a branch for longint changes? In-Reply-To: References: Message-ID: <920B991F-A50E-43D9-86AB-1E387DE24DA9@cs.purdue.edu> Please hold off on mainline changes. I don't think we have reached consensus yet... The issue remains: mixed arithmetic + checked assignability or not? I'm leaning towards allowing it, but want to hear from others. On 8 Jan 2010, at 21:16, Jay K wrote: > Still need a branch for longint changes? > I doubt what I have is where we are going, though it is a step toward it. > Just wait for Tony to implement Rodney's proposal? > Or I work on it in a branch? It doesn't look too difficult to at least mostly do. I already have "mixed" stuff compiling and assignability INTEGER to LONGINT. I didn't yet do anything requiring runtime checks, but it's not that hard to do, given that there are already checks for assignment involving only partly overlapping ranges. > > Or maybe just take my stuff to the mainline and then refine/reduce it later? > > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 9 03:28:59 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 21:28:59 -0500 Subject: [M3devel] Unbounded but finite LONGINT (was: Re: Integers In-Reply-To: <20100109014437.GC23519@topoi.pooq.com> References: <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <20100108215028.40A651A207A@async.async.caltech.edu> <20100108230505.GC9749@topoi.pooq.com> <20100109013342.GA23519@topoi.pooq.com> <20100109014437.GC23519@topoi.pooq.com> Message-ID: <7A1B4E83-A69C-43CA-9932-38B974B22B60@cs.purdue.edu> I'm not sure how this would all work exactly... It would make LONGINT a very strange beast indeed, compared to the other ordinal types. On 8 Jan 2010, at 20:44, hendrik at topoi.pooq.com wrote: > On Fri, Jan 08, 2010 at 08:33:42PM -0500, hendrik at topoi.pooq.com wrote: >> On Fri, Jan 08, 2010 at 07:53:07PM -0500, Tony Hosking wrote: >>> I think what you are advocating is Rodney's proposal + assignability >>> of INTEGER and LONGINT + mixed arithmetic. >> >> I thought Rodney's propsal still had the compiler impose a bound on the >> size of LONGINT. Or did I miss something? > > In particular, I would have there be no FIRST(LONGINT) or LAST(LONGINT). > > -- hendrik >> >> I'm proposing to let the programmer use subranges of LONGINT that are as >> long as he wishes. And if the computer runs out of virtual memory to >> store one of the programmer's long integers, well, that's the computer >> imposing the limit, not the language. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 9 03:32:47 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Fri, 8 Jan 2010 21:32:47 -0500 Subject: [M3devel] Unbounded but finite LONGINT (was: Re: Integers In-Reply-To: <20100109013342.GA23519@topoi.pooq.com> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <20100108215028.40A651A207A@async.async.caltech.edu> <20100108230505.GC9749@topoi.pooq.com> <20100109013342.GA23519@topoi.pooq.com> Message-ID: <99206B8B-5004-4D0C-966B-0CBC0D6A6AD8@cs.purdue.edu> On 8 Jan 2010, at 20:33, hendrik at topoi.pooq.com wrote: > On Fri, Jan 08, 2010 at 07:53:07PM -0500, Tony Hosking wrote: >> I think what you are advocating is Rodney's proposal + assignability >> of INTEGER and LONGINT + mixed arithmetic. > > I thought Rodney's propsal still had the compiler impose a bound on the > size of LONGINT. Or did I miss something? Yes, it would. > I'm proposing to let the programmer use subranges of LONGINT that are as > long as he wishes. And if the computer runs out of virtual memory to > store one of the programmer's long integers, well, that's the computer > imposing the limit, not the language. But there is still the question as to what *representation* is used to decide the particular operation to apply. I suppose the compiler could choose a particular machine representation based on the range of values in the subrange (much as it does currently). But if you really want to have an arbitrary range type I would argue it is much better to implement it as a library than as a primitive type. Just for fun, I suggest you take some time to watch the talk Growing a Language, by Guy Steele -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Jan 9 03:36:54 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 02:36:54 +0000 Subject: [M3devel] still need a branch for longint changes? In-Reply-To: <920B991F-A50E-43D9-86AB-1E387DE24DA9@cs.purdue.edu> References: , <920B991F-A50E-43D9-86AB-1E387DE24DA9@cs.purdue.edu> Message-ID: I'm fine with a compromise that requires no runtime checks and users use ORD() to narrow LONGINT to INTEGER. And mixed arithmetic is available, and assignability INTEGER to LONGINT. I have that implemented. It is a little onerous for Rd/Wr uses, but ok. - Jay From: hosking at cs.purdue.edu Date: Fri, 8 Jan 2010 21:23:15 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] still need a branch for longint changes? Please hold off on mainline changes. I don't think we have reached consensus yet... The issue remains: mixed arithmetic + checked assignability or not? I'm leaning towards allowing it, but want to hear from others. On 8 Jan 2010, at 21:16, Jay K wrote: Still need a branch for longint changes? I doubt what I have is where we are going, though it is a step toward it. Just wait for Tony to implement Rodney's proposal? Or I work on it in a branch? It doesn't look too difficult to at least mostly do. I already have "mixed" stuff compiling and assignability INTEGER to LONGINT. I didn't yet do anything requiring runtime checks, but it's not that hard to do, given that there are already checks for assignment involving only partly overlapping ranges. Or maybe just take my stuff to the mainline and then refine/reduce it later? - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hendrik at topoi.pooq.com Sat Jan 9 04:00:41 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 22:00:41 -0500 Subject: [M3devel] Unbounded but finite LONGINT (was: Re: Integers In-Reply-To: <99206B8B-5004-4D0C-966B-0CBC0D6A6AD8@cs.purdue.edu> References: <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <20100108215028.40A651A207A@async.async.caltech.edu> <20100108230505.GC9749@topoi.pooq.com> <20100109013342.GA23519@topoi.pooq.com> <99206B8B-5004-4D0C-966B-0CBC0D6A6AD8@cs.purdue.edu> Message-ID: <20100109030040.GA28707@topoi.pooq.com> On Fri, Jan 08, 2010 at 09:32:47PM -0500, Tony Hosking wrote: > On 8 Jan 2010, at 20:33, hendrik at topoi.pooq.com wrote: > > > On Fri, Jan 08, 2010 at 07:53:07PM -0500, Tony Hosking wrote: > >> I think what you are advocating is Rodney's proposal + assignability > >> of INTEGER and LONGINT + mixed arithmetic. > > > > I thought Rodney's propsal still had the compiler impose a bound on the > > size of LONGINT. Or did I miss something? > > Yes, it would. > > > I'm proposing to let the programmer use subranges of LONGINT that are as > > long as he wishes. And if the computer runs out of virtual memory to > > store one of the programmer's long integers, well, that's the computer > > imposing the limit, not the language. > > But there is still the question as to what *representation* is used to decide the particular operation to apply. > > I suppose the compiler could choose a particular machine > representation based on the range of values in the subrange (much as > it does currently). That's exactly what I propose. > But if you really want to have an arbitrary range type I would argue > it is much better to implement it as a library than as a primitive > type. That's fine if I have no static limit on the size of the integers. Like if I want to have an open array. Or even an array that I can resize dynamically. But for the common case where I know exactly what the limits are, static is better. (and that's the case with file offsets, for example) What's easier for the compiler writer is another matter, of course. > > Just for fun, I suggest you take some time to watch the talk Growing a > Language, by Guy Steele I'll try and find it. I seem to remember seeing the text somewhere. -- hendrik From hendrik at topoi.pooq.com Sat Jan 9 04:03:15 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Fri, 8 Jan 2010 22:03:15 -0500 Subject: [M3devel] still need a branch for longint changes? In-Reply-To: <920B991F-A50E-43D9-86AB-1E387DE24DA9@cs.purdue.edu> References: <920B991F-A50E-43D9-86AB-1E387DE24DA9@cs.purdue.edu> Message-ID: <20100109030314.GB28707@topoi.pooq.com> On Fri, Jan 08, 2010 at 09:23:15PM -0500, Tony Hosking wrote: > Please hold off on mainline changes. I don't think we have reached > consensus yet... > > The issue remains: mixed arithmetic + checked assignability or not? > I'm leaning towards allowing it, but want to hear from others. Not to mention the question whether the conpiler should impose a static bound on LONGINT. -- hendrik From jay.krell at cornell.edu Sat Jan 9 04:54:31 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 03:54:31 +0000 Subject: [M3devel] mixing INTEGER and LONGINT? In-Reply-To: <20100108142811.GA14151@topoi.pooq.com> References: , <20100108142811.GA14151@topoi.pooq.com> Message-ID: Oops, of course, thank you. I'll update my changes...maybe check them into a branch.. - Jay > From: hendrik > MIN( 5, -1000000000000000L) = -1000000000000000L > So the result really needs to be LONGINT. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 9 06:06:07 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 00:06:07 -0500 Subject: [M3devel] still need a branch for longint changes? In-Reply-To: References: , <920B991F-A50E-43D9-86AB-1E387DE24DA9@cs.purdue.edu> Message-ID: <77A73750-12DF-4BB2-B6AF-6919FC2687FE@cs.purdue.edu> So, thinking about things some more I am very much less inclined to believe that mixed operand arithmetic makes any sense, though assignability with run-time range checks seems fine. With mixed operand arithmetic we get to some very strange places: LAST(INTEGER) + 1 = FIRST(INTEGER) is true because of overflow under the standard Modula-3 implementation. But, LAST(INTEGER) + 1L = FIRST(INTEGER) is false because the arithmetic will be performed as LONGINT. The trivial presence of "1L" instead of "1" has a huge impact on the semantics. That seems really dangerous. Much better (if wordier) to require explicit conversion (as currently implemented) to preserve sanity. Thus, VAL(LAST(INTEGER), LONGINT) + 1L = VAL(FIRST(INTEGER), LONGINT) is false, as the programmer rightly expects, because he/she will be explicitly (because of the conversions) aware that LONGINT arithmetic is taking place. On 8 Jan 2010, at 21:36, Jay K wrote: > I'm fine with a compromise that requires no runtime checks and users use ORD() to narrow LONGINT to INTEGER. > And mixed arithmetic is available, and assignability INTEGER to LONGINT. > I have that implemented. It is a little onerous for Rd/Wr uses, but ok. > > - Jay > > > From: hosking at cs.purdue.edu > Date: Fri, 8 Jan 2010 21:23:15 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] still need a branch for longint changes? > > Please hold off on mainline changes. I don't think we have reached consensus yet... > > The issue remains: mixed arithmetic + checked assignability or not? I'm leaning towards allowing it, but want to hear from others. > > On 8 Jan 2010, at 21:16, Jay K wrote: > > Still need a branch for longint changes? > I doubt what I have is where we are going, though it is a step toward it. > Just wait for Tony to implement Rodney's proposal? > Or I work on it in a branch? It doesn't look too difficult to at least mostly do. I already have "mixed" stuff compiling and assignability INTEGER to LONGINT. I didn't yet do anything requiring runtime checks, but it's not that hard to do, given that there are already checks for assignment involving only partly overlapping ranges. > > Or maybe just take my stuff to the mainline and then refine/reduce it later? > > - Jay > > > From hosking at cs.purdue.edu Sat Jan 9 06:37:42 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 00:37:42 -0500 Subject: [M3devel] latest longint file size diffs In-Reply-To: References: Message-ID: <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu> Looking at your code, I think the assignability test for ordinals should be more like: IF (IsEqual (Base(a), Base(b), NIL) OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) AND GetBounds (a, min_a, max_a) AND GetBounds (b, min_b, max_b) THEN (* check for a non-empty intersection *) min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; RETURN TInt.LE (min, max); ELSE RETURN FALSE; END; That way CARDINAL and other subranges fall right out. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On 8 Jan 2010, at 06:13, Jay K wrote: > Attached is my latest work here. > With the compiler changes (in the diff), I was able to > elminate most uses of VAL(expr, LONGINT). > There's something slightly off such that I had > to add a very small number, like two. > > > The compiler change is newer than earlier. > For example you can now assign CARDINAL to LONGINT. > I didn't do it, but you should also be able to add/subtract/etc. > mixing CARDINAL and LONGINT. > > > FOR statements also don't allow the level of mixing > that they should. > > > I'm hoping to get agreement soon just from the diffs > but if necessary I'll look how to create a branch. > My general worry about branches is developers just > go off on their own in a branch and it's impossible to > get anyone to look at it, they are busy enough with one branch, > let alone multiple.. > > > - Jay > From jay.krell at cornell.edu Sat Jan 9 06:50:06 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 05:50:06 +0000 Subject: [M3devel] latest longint file size diffs In-Reply-To: <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu> References: , <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu> Message-ID: I don't know the precedence but agreed: > OR (IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL)) > OR (IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL))) I was being sort of lazy. I've never touched the front end and it was critical I be able to make a small change and see fairly precisely the expected change, even if I didn't get all cases. This is I'm sure why I had to add some VAL/ORD uses, to convert "UINT32" in the Win32 code to INTEGER or LONGINT. Also, I really think mixed arithmetic is ok. - Jay > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 00:37:42 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] latest longint file size diffs > > Looking at your code, I think the assignability test for ordinals should be more like: > > IF (IsEqual (Base(a), Base(b), NIL) > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > AND GetBounds (a, min_a, max_a) > AND GetBounds (b, min_b, max_b) THEN > (* check for a non-empty intersection *) > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > RETURN TInt.LE (min, max); > ELSE > RETURN FALSE; > END; > > That way CARDINAL and other subranges fall right out. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On 8 Jan 2010, at 06:13, Jay K wrote: > > > Attached is my latest work here. > > With the compiler changes (in the diff), I was able to > > elminate most uses of VAL(expr, LONGINT). > > There's something slightly off such that I had > > to add a very small number, like two. > > > > > > The compiler change is newer than earlier. > > For example you can now assign CARDINAL to LONGINT. > > I didn't do it, but you should also be able to add/subtract/etc. > > mixing CARDINAL and LONGINT. > > > > > > FOR statements also don't allow the level of mixing > > that they should. > > > > > > I'm hoping to get agreement soon just from the diffs > > but if necessary I'll look how to create a branch. > > My general worry about branches is developers just > > go off on their own in a branch and it's impossible to > > get anyone to look at it, they are busy enough with one branch, > > let alone multiple.. > > > > > > - Jay > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 9 07:03:08 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 01:03:08 -0500 Subject: [M3devel] latest longint file size diffs In-Reply-To: References: , <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu> Message-ID: <98228FAE-31EB-43CA-83CB-58FE7323A964@cs.purdue.edu> On 9 Jan 2010, at 00:50, Jay K wrote: > I don't know the precedence but agreed: > > > > OR (IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL)) > > OR (IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL))) > > I was being sort of lazy. > I've never touched the front end and it was critical I be able to make > a small change and see fairly precisely the expected change, even > if I didn't get all cases. > > This is I'm sure why I had to add some VAL/ORD uses, to convert "UINT32" > in the Win32 code to INTEGER or LONGINT. Yes, that would be why. > Also, I really think mixed arithmetic is ok. But are you ok with: (LAST(INTEGER) + 1) = FIRST(INTEGER) while (LAST(INTEGER) + 1L) # FIRST(INTEGER) ? I find such things to be difficult to explain to the novice programmer. Modula-3 was designed using the "principle of least surprise" and I frankly find the above to be very surprising! > > - Jay > > > > From: hosking at cs.purdue.edu > > Date: Sat, 9 Jan 2010 00:37:42 -0500 > > To: jay.krell at cornell.edu > > CC: m3devel at elegosoft.com > > Subject: Re: [M3devel] latest longint file size diffs > > > > Looking at your code, I think the assignability test for ordinals should be more like: > > > > IF (IsEqual (Base(a), Base(b), NIL) > > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > > AND GetBounds (a, min_a, max_a) > > AND GetBounds (b, min_b, max_b) THEN > > (* check for a non-empty intersection *) > > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > > RETURN TInt.LE (min, max); > > ELSE > > RETURN FALSE; > > END; > > > > That way CARDINAL and other subranges fall right out. > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > > 305 N. University Street | West Lafayette | IN 47907 | USA > > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > > > > > > On 8 Jan 2010, at 06:13, Jay K wrote: > > > > > Attached is my latest work here. > > > With the compiler changes (in the diff), I was able to > > > elminate most uses of VAL(expr, LONGINT). > > > There's something slightly off such that I had > > > to add a very small number, like two. > > > > > > > > > The compiler change is newer than earlier. > > > For example you can now assign CARDINAL to LONGINT. > > > I didn't do it, but you should also be able to add/subtract/etc. > > > mixing CARDINAL and LONGINT. > > > > > > > > > FOR statements also don't allow the level of mixing > > > that they should. > > > > > > > > > I'm hoping to get agreement soon just from the diffs > > > but if necessary I'll look how to create a branch. > > > My general worry about branches is developers just > > > go off on their own in a branch and it's impossible to > > > get anyone to look at it, they are busy enough with one branch, > > > let alone multiple.. > > > > > > > > > - Jay > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Jan 9 07:59:52 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 06:59:52 +0000 Subject: [M3devel] latest longint file size diffs In-Reply-To: <98228FAE-31EB-43CA-83CB-58FE7323A964@cs.purdue.edu> References: , , <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu>, , <98228FAE-31EB-43CA-83CB-58FE7323A964@cs.purdue.edu> Message-ID: I'll admit to being a little unsure. I do hope the rd/wr change can be done with a small diff, maybe nothing outside libm3. You might classify me more as a lazy user than a language designing deep thinker. But I'm curious even about your assertion. Let's pretend INTEGER is 8 bits and LONGINT is 16 bits, ok? It is easier for me. INTEGER max := 16_7F; INTEGER first := 16_80; INTEGER p1 := max + 1; LONGINT p1L := max + 1L; So, what happens if we compare p1 with first and p1L with first? Again remember INTEGER is 8 bits, LONGINT is 16 bits. p1 will be -128, 0x80. p1L will be 128, 0x0080. What then happens when you compare 0x0080 to 0x80? Are they equal (truncate both to INTEGER and compare), unequal (sign extend to LONGINT and compare), or you get an exception (upon narrowing the LONGINT to INTEGER and it doesn't fit)? And heck, shouldn't max + 1 already throw an exception? - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 01:03:08 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] latest longint file size diffs On 9 Jan 2010, at 00:50, Jay K wrote:I don't know the precedence but agreed: > OR (IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL)) > OR (IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL))) I was being sort of lazy. I've never touched the front end and it was critical I be able to make a small change and see fairly precisely the expected change, even if I didn't get all cases. This is I'm sure why I had to add some VAL/ORD uses, to convert "UINT32" in the Win32 code to INTEGER or LONGINT. Yes, that would be why. Also, I really think mixed arithmetic is ok. But are you ok with: (LAST(INTEGER) + 1) = FIRST(INTEGER) while (LAST(INTEGER) + 1L) # FIRST(INTEGER) ? I find such things to be difficult to explain to the novice programmer. Modula-3 was designed using the "principle of least surprise" and I frankly find the above to be very surprising! - Jay > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 00:37:42 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] latest longint file size diffs > > Looking at your code, I think the assignability test for ordinals should be more like: > > IF (IsEqual (Base(a), Base(b), NIL) > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > AND GetBounds (a, min_a, max_a) > AND GetBounds (b, min_b, max_b) THEN > (* check for a non-empty intersection *) > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > RETURN TInt.LE (min, max); > ELSE > RETURN FALSE; > END; > > That way CARDINAL and other subranges fall right out. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On 8 Jan 2010, at 06:13, Jay K wrote: > > > Attached is my latest work here. > > With the compiler changes (in the diff), I was able to > > elminate most uses of VAL(expr, LONGINT). > > There's something slightly off such that I had > > to add a very small number, like two. > > > > > > The compiler change is newer than earlier. > > For example you can now assign CARDINAL to LONGINT. > > I didn't do it, but you should also be able to add/subtract/etc. > > mixing CARDINAL and LONGINT. > > > > > > FOR statements also don't allow the level of mixing > > that they should. > > > > > > I'm hoping to get agreement soon just from the diffs > > but if necessary I'll look how to create a branch. > > My general worry about branches is developers just > > go off on their own in a branch and it's impossible to > > get anyone to look at it, they are busy enough with one branch, > > let alone multiple.. > > > > > > - Jay > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Jan 9 08:01:47 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 07:01:47 +0000 Subject: [M3devel] latest longint file size diffs In-Reply-To: <98228FAE-31EB-43CA-83CB-58FE7323A964@cs.purdue.edu> References: , , <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu>, , <98228FAE-31EB-43CA-83CB-58FE7323A964@cs.purdue.edu> Message-ID: > (LAST(INTEGER) + 1) = FIRST(INTEGER) ps: a beginner wouldn't necessarily expect this. He might expect an error or widening of precision as needed. Eventually faced with the cruel realities of what can be efficiently implemented, he might accept any of our answers. :) - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com Subject: RE: [M3devel] latest longint file size diffs Date: Sat, 9 Jan 2010 06:59:52 +0000 I'll admit to being a little unsure. I do hope the rd/wr change can be done with a small diff, maybe nothing outside libm3. You might classify me more as a lazy user than a language designing deep thinker. But I'm curious even about your assertion. Let's pretend INTEGER is 8 bits and LONGINT is 16 bits, ok? It is easier for me. INTEGER max := 16_7F; INTEGER first := 16_80; INTEGER p1 := max + 1; LONGINT p1L := max + 1L; So, what happens if we compare p1 with first and p1L with first? Again remember INTEGER is 8 bits, LONGINT is 16 bits. p1 will be -128, 0x80. p1L will be 128, 0x0080. What then happens when you compare 0x0080 to 0x80? Are they equal (truncate both to INTEGER and compare), unequal (sign extend to LONGINT and compare), or you get an exception (upon narrowing the LONGINT to INTEGER and it doesn't fit)? And heck, shouldn't max + 1 already throw an exception? - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 01:03:08 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] latest longint file size diffs On 9 Jan 2010, at 00:50, Jay K wrote:I don't know the precedence but agreed: > OR (IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL)) > OR (IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL))) I was being sort of lazy. I've never touched the front end and it was critical I be able to make a small change and see fairly precisely the expected change, even if I didn't get all cases. This is I'm sure why I had to add some VAL/ORD uses, to convert "UINT32" in the Win32 code to INTEGER or LONGINT. Yes, that would be why. Also, I really think mixed arithmetic is ok. But are you ok with: (LAST(INTEGER) + 1) = FIRST(INTEGER) while (LAST(INTEGER) + 1L) # FIRST(INTEGER) ? I find such things to be difficult to explain to the novice programmer. Modula-3 was designed using the "principle of least surprise" and I frankly find the above to be very surprising! - Jay > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 00:37:42 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] latest longint file size diffs > > Looking at your code, I think the assignability test for ordinals should be more like: > > IF (IsEqual (Base(a), Base(b), NIL) > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > AND GetBounds (a, min_a, max_a) > AND GetBounds (b, min_b, max_b) THEN > (* check for a non-empty intersection *) > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > RETURN TInt.LE (min, max); > ELSE > RETURN FALSE; > END; > > That way CARDINAL and other subranges fall right out. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On 8 Jan 2010, at 06:13, Jay K wrote: > > > Attached is my latest work here. > > With the compiler changes (in the diff), I was able to > > elminate most uses of VAL(expr, LONGINT). > > There's something slightly off such that I had > > to add a very small number, like two. > > > > > > The compiler change is newer than earlier. > > For example you can now assign CARDINAL to LONGINT. > > I didn't do it, but you should also be able to add/subtract/etc. > > mixing CARDINAL and LONGINT. > > > > > > FOR statements also don't allow the level of mixing > > that they should. > > > > > > I'm hoping to get agreement soon just from the diffs > > but if necessary I'll look how to create a branch. > > My general worry about branches is developers just > > go off on their own in a branch and it's impossible to > > get anyone to look at it, they are busy enough with one branch, > > let alone multiple.. > > > > > > - Jay > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Jan 9 08:52:29 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 07:52:29 +0000 Subject: [M3devel] latest longint file size diffs In-Reply-To: References: , , , <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu>, , , , <98228FAE-31EB-43CA-83CB-58FE7323A964@cs.purdue.edu>, Message-ID: ok, yeah, it does bug me. With 8 bit integer, 16 bit longint. Let's replace 128 with 127 + 1. (127 + 1) > 127 either: is true or false or raises an exception "Obviously" it should be true, but implementing that is..uncertain. Though, again, it should really raise the exception before the comparison is made. Maybe it does. Where (127 + 1L) > 127 is simply true, no controversy..except for the difference with 127 + 1. But Rodney said something..that mixed operations fall out of assignability. Right?? I have an idea..I mean..an obvious guess/experiment. I can try providing only for bidirectional assignability and see what the affect on rd/wr is. Maybe bidirectional assignability is enough to keep the diff small? Or, maybe my initial big diff with ORD/VAL everywhere is acceptable? Clearly it will be allowed by any of the proposals, it just might not be necessary. Also, btw, I think we should warn for truncating assignment. Any time a range check is put in, perhaps. Except maybe not on array indexing. Which might leave this suggestion completely ambiguous as to when a warning should be issued. But as has been pointed out, while it may be "annoying" and "inconvenient" to put ORD and VAL everywhere, or at least ORD, it does force us to revisit all those locations where a change is being induced. Notice that that the warning may or may not be platform specific. It might trigger only on 32bit platforms. Or the compiler targeting 64bit platforms might "know" about the truncation potential on other platforms and warn. In a specific concrete way, assignment of LONGINT to INTEGER might warn, no matter their current exact sizes. Extending that rule to subranges might be tricky. TYPE A = [0..LAST(INTEGER)/2]; TYPE B = [0..LAST(LONGINT)/2]; VAR a: A; b:B; a := b; warn? Implementing that, maybe, would require, like a bit carried along with type definitions in the compiler, as to if the definition contains a platform independent size in it...er.. if the size is dependent on bitsize(integer) or not, and mixing of that type with any? other type is a warning? Clearly no. Mixing with a type dependent on bitsize(longint)? Maybe. I'm not sure what the rule is, but, you know, it'd be nice if above code did warn on 64bit targets, in order to encourage portability to 32bit targets. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 07:01:47 +0000 CC: m3devel at elegosoft.com Subject: Re: [M3devel] latest longint file size diffs > (LAST(INTEGER) + 1) = FIRST(INTEGER) ps: a beginner wouldn't necessarily expect this. He might expect an error or widening of precision as needed. Eventually faced with the cruel realities of what can be efficiently implemented, he might accept any of our answers. :) - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com Subject: RE: [M3devel] latest longint file size diffs Date: Sat, 9 Jan 2010 06:59:52 +0000 I'll admit to being a little unsure. I do hope the rd/wr change can be done with a small diff, maybe nothing outside libm3. You might classify me more as a lazy user than a language designing deep thinker. But I'm curious even about your assertion. Let's pretend INTEGER is 8 bits and LONGINT is 16 bits, ok? It is easier for me. INTEGER max := 16_7F; INTEGER first := 16_80; INTEGER p1 := max + 1; LONGINT p1L := max + 1L; So, what happens if we compare p1 with first and p1L with first? Again remember INTEGER is 8 bits, LONGINT is 16 bits. p1 will be -128, 0x80. p1L will be 128, 0x0080. What then happens when you compare 0x0080 to 0x80? Are they equal (truncate both to INTEGER and compare), unequal (sign extend to LONGINT and compare), or you get an exception (upon narrowing the LONGINT to INTEGER and it doesn't fit)? And heck, shouldn't max + 1 already throw an exception? - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 01:03:08 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] latest longint file size diffs On 9 Jan 2010, at 00:50, Jay K wrote:I don't know the precedence but agreed: > OR (IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL)) > OR (IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL))) I was being sort of lazy. I've never touched the front end and it was critical I be able to make a small change and see fairly precisely the expected change, even if I didn't get all cases. This is I'm sure why I had to add some VAL/ORD uses, to convert "UINT32" in the Win32 code to INTEGER or LONGINT. Yes, that would be why. Also, I really think mixed arithmetic is ok. But are you ok with: (LAST(INTEGER) + 1) = FIRST(INTEGER) while (LAST(INTEGER) + 1L) # FIRST(INTEGER) ? I find such things to be difficult to explain to the novice programmer. Modula-3 was designed using the "principle of least surprise" and I frankly find the above to be very surprising! - Jay > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 00:37:42 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] latest longint file size diffs > > Looking at your code, I think the assignability test for ordinals should be more like: > > IF (IsEqual (Base(a), Base(b), NIL) > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > AND GetBounds (a, min_a, max_a) > AND GetBounds (b, min_b, max_b) THEN > (* check for a non-empty intersection *) > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > RETURN TInt.LE (min, max); > ELSE > RETURN FALSE; > END; > > That way CARDINAL and other subranges fall right out. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On 8 Jan 2010, at 06:13, Jay K wrote: > > > Attached is my latest work here. > > With the compiler changes (in the diff), I was able to > > elminate most uses of VAL(expr, LONGINT). > > There's something slightly off such that I had > > to add a very small number, like two. > > > > > > The compiler change is newer than earlier. > > For example you can now assign CARDINAL to LONGINT. > > I didn't do it, but you should also be able to add/subtract/etc. > > mixing CARDINAL and LONGINT. > > > > > > FOR statements also don't allow the level of mixing > > that they should. > > > > > > I'm hoping to get agreement soon just from the diffs > > but if necessary I'll look how to create a branch. > > My general worry about branches is developers just > > go off on their own in a branch and it's impossible to > > get anyone to look at it, they are busy enough with one branch, > > let alone multiple.. > > > > > > - Jay > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Jan 9 10:04:03 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 09:04:03 +0000 Subject: [M3devel] latest longint file size diffs In-Reply-To: References: , , , , <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu>, , , , <98228FAE-31EB-43CA-83CB-58FE7323A964@cs.purdue.edu>, Message-ID: Uh, maybe all ordinal types that overlap in any values are assignable? PROCEDURE IsAssignable (a, b: T): BOOLEAN = VAR i, e: T; min_a, max_a, min_b, max_b, min, max: Target.Int; BEGIN IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN RETURN TRUE; ELSIF IsOrdinal (a) THEN (* ordinal types: OK if they have at least one member in common. *) IF GetBounds (a, min_a, max_a) AND GetBounds (b, min_b, max_b) THEN (* check for a non-empty intersection *) min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; RETURN TInt.LE (min, max); ELSE RETURN FALSE; END; ELSIF IsSubtype (a, b) THEN (* may be ok, but must narrow rhs before doing the assignment *) RETURN IsSubtype (b, Reff.T) OR ArrayType.Split (b, i, e) OR (IsSubtype (b, Addr.T) AND (NOT Module.IsSafe() OR NOT IsEqual (b, Addr.T, NIL))); ELSE RETURN FALSE; END; END IsAssignable; ? I'll try it out. What is an ordinal type?, I wonder, the compiler implementation: PROCEDURE IsOrdinal (t: T): BOOLEAN = VAR u := Check (t); c := u.info.class; BEGIN RETURN (c = Class.Integer) OR (c = Class.Longint) OR (c = Class.Subrange) OR (c = Class.Enum) OR (c = Class.Error) OR ((c = Class.Packed) AND IsOrdinal (StripPacked (t))); END IsOrdinal; - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com Subject: RE: [M3devel] latest longint file size diffs Date: Sat, 9 Jan 2010 07:52:29 +0000 ok, yeah, it does bug me. With 8 bit integer, 16 bit longint. Let's replace 128 with 127 + 1. (127 + 1) > 127 either: is true or false or raises an exception "Obviously" it should be true, but implementing that is..uncertain. Though, again, it should really raise the exception before the comparison is made. Maybe it does. Where (127 + 1L) > 127 is simply true, no controversy..except for the difference with 127 + 1. But Rodney said something..that mixed operations fall out of assignability. Right?? I have an idea..I mean..an obvious guess/experiment. I can try providing only for bidirectional assignability and see what the affect on rd/wr is. Maybe bidirectional assignability is enough to keep the diff small? Or, maybe my initial big diff with ORD/VAL everywhere is acceptable? Clearly it will be allowed by any of the proposals, it just might not be necessary. Also, btw, I think we should warn for truncating assignment. Any time a range check is put in, perhaps. Except maybe not on array indexing. Which might leave this suggestion completely ambiguous as to when a warning should be issued. But as has been pointed out, while it may be "annoying" and "inconvenient" to put ORD and VAL everywhere, or at least ORD, it does force us to revisit all those locations where a change is being induced. Notice that that the warning may or may not be platform specific. It might trigger only on 32bit platforms. Or the compiler targeting 64bit platforms might "know" about the truncation potential on other platforms and warn. In a specific concrete way, assignment of LONGINT to INTEGER might warn, no matter their current exact sizes. Extending that rule to subranges might be tricky. TYPE A = [0..LAST(INTEGER)/2]; TYPE B = [0..LAST(LONGINT)/2]; VAR a: A; b:B; a := b; warn? Implementing that, maybe, would require, like a bit carried along with type definitions in the compiler, as to if the definition contains a platform independent size in it...er.. if the size is dependent on bitsize(integer) or not, and mixing of that type with any? other type is a warning? Clearly no. Mixing with a type dependent on bitsize(longint)? Maybe. I'm not sure what the rule is, but, you know, it'd be nice if above code did warn on 64bit targets, in order to encourage portability to 32bit targets. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 07:01:47 +0000 CC: m3devel at elegosoft.com Subject: Re: [M3devel] latest longint file size diffs > (LAST(INTEGER) + 1) = FIRST(INTEGER) ps: a beginner wouldn't necessarily expect this. He might expect an error or widening of precision as needed. Eventually faced with the cruel realities of what can be efficiently implemented, he might accept any of our answers. :) - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com Subject: RE: [M3devel] latest longint file size diffs Date: Sat, 9 Jan 2010 06:59:52 +0000 I'll admit to being a little unsure. I do hope the rd/wr change can be done with a small diff, maybe nothing outside libm3. You might classify me more as a lazy user than a language designing deep thinker. But I'm curious even about your assertion. Let's pretend INTEGER is 8 bits and LONGINT is 16 bits, ok? It is easier for me. INTEGER max := 16_7F; INTEGER first := 16_80; INTEGER p1 := max + 1; LONGINT p1L := max + 1L; So, what happens if we compare p1 with first and p1L with first? Again remember INTEGER is 8 bits, LONGINT is 16 bits. p1 will be -128, 0x80. p1L will be 128, 0x0080. What then happens when you compare 0x0080 to 0x80? Are they equal (truncate both to INTEGER and compare), unequal (sign extend to LONGINT and compare), or you get an exception (upon narrowing the LONGINT to INTEGER and it doesn't fit)? And heck, shouldn't max + 1 already throw an exception? - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 01:03:08 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] latest longint file size diffs On 9 Jan 2010, at 00:50, Jay K wrote: I don't know the precedence but agreed: > OR (IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL)) > OR (IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL))) I was being sort of lazy. I've never touched the front end and it was critical I be able to make a small change and see fairly precisely the expected change, even if I didn't get all cases. This is I'm sure why I had to add some VAL/ORD uses, to convert "UINT32" in the Win32 code to INTEGER or LONGINT. Yes, that would be why. Also, I really think mixed arithmetic is ok. But are you ok with: (LAST(INTEGER) + 1) = FIRST(INTEGER) while (LAST(INTEGER) + 1L) # FIRST(INTEGER) ? I find such things to be difficult to explain to the novice programmer. Modula-3 was designed using the "principle of least surprise" and I frankly find the above to be very surprising! - Jay > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 00:37:42 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] latest longint file size diffs > > Looking at your code, I think the assignability test for ordinals should be more like: > > IF (IsEqual (Base(a), Base(b), NIL) > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > AND GetBounds (a, min_a, max_a) > AND GetBounds (b, min_b, max_b) THEN > (* check for a non-empty intersection *) > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > RETURN TInt.LE (min, max); > ELSE > RETURN FALSE; > END; > > That way CARDINAL and other subranges fall right out. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On 8 Jan 2010, at 06:13, Jay K wrote: > > > Attached is my latest work here. > > With the compiler changes (in the diff), I was able to > > elminate most uses of VAL(expr, LONGINT). > > There's something slightly off such that I had > > to add a very small number, like two. > > > > > > The compiler change is newer than earlier. > > For example you can now assign CARDINAL to LONGINT. > > I didn't do it, but you should also be able to add/subtract/etc. > > mixing CARDINAL and LONGINT. > > > > > > FOR statements also don't allow the level of mixing > > that they should. > > > > > > I'm hoping to get agreement soon just from the diffs > > but if necessary I'll look how to create a branch. > > My general worry about branches is developers just > > go off on their own in a branch and it's impossible to > > get anyone to look at it, they are busy enough with one branch, > > let alone multiple.. > > > > > > - Jay > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Jan 9 10:34:06 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 09:34:06 +0000 Subject: [M3devel] index array by longint? Message-ID: Index array by longint? With runtime check that it is <= LAST(INTEGER)? Or really, with runtime bounds check against the array size. Seems reasonable? Aids the rd/wr change. A little bit of pain to implement..unless INTEGER and LONGINT have a common base... - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Jan 9 11:22:21 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 10:22:21 +0000 Subject: [M3devel] another longint variant Message-ID: [attached] In this variant, the compiler has been made "maximally lenient" and the rd/wr changes are minimized. Specifically: compiler allows assignment either way and various math operations, including NEW array and array subscript. mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) rd/wr changes outside libm3 are only changing the signatures of Seek and Length pretty minimal, and hard to imagine they could be smaller, though actually they could..well..the need to fix existing rd/wr could be eliminated/delayed rd/wr could introduce SeekL, LengthL which by default call Seek/Length, and then rd/wr could gradually convert, and not gain 4GB capability until then no VAL or ORD needed some rd/wr implementations might be artificially limited to 4G simply because they don't chane some INTEGER to LONGINT; "anything compiles" some of the compiler changes are probably slightly off or incomplete including a need to insert the checks for LONGINT => INTEGER -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: dif3.txt URL: From hosking at cs.purdue.edu Sat Jan 9 19:24:08 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 13:24:08 -0500 Subject: [M3devel] latest longint file size diffs In-Reply-To: References: , , , , <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu>, , , , <98228FAE-31EB-43CA-83CB-58FE7323A964@cs.purdue.edu>, Message-ID: <0D79BD22-2EB9-4EC8-A453-CC2E0A66AA8C@cs.purdue.edu> The patch I sent to you yesterday will achieve checked assignment of LONGINT to/from INTEGER. On 9 Jan 2010, at 04:04, Jay K wrote: > Uh, maybe all ordinal types that overlap in any values are assignable? > > > PROCEDURE IsAssignable (a, b: T): BOOLEAN = > VAR i, e: T; min_a, max_a, min_b, max_b, min, max: Target.Int; > BEGIN > IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN > RETURN TRUE; > ELSIF IsOrdinal (a) THEN > (* ordinal types: OK if they have at least one member in common. *) > IF GetBounds (a, min_a, max_a) > AND GetBounds (b, min_b, max_b) THEN > (* check for a non-empty intersection *) > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > RETURN TInt.LE (min, max); > ELSE > RETURN FALSE; > END; > ELSIF IsSubtype (a, b) THEN > (* may be ok, but must narrow rhs before doing the assignment *) > RETURN IsSubtype (b, Reff.T) > OR ArrayType.Split (b, i, e) > OR (IsSubtype (b, Addr.T) > AND (NOT Module.IsSafe() OR NOT IsEqual (b, Addr.T, NIL))); > ELSE > RETURN FALSE; > END; > END IsAssignable; > > > ? > I'll try it out. > > > What is an ordinal type?, I wonder, the compiler implementation: > > > PROCEDURE IsOrdinal (t: T): BOOLEAN = > VAR u := Check (t); c := u.info.class; > BEGIN > RETURN (c = Class.Integer) OR (c = Class.Longint) OR (c = Class.Subrange) > OR (c = Class.Enum) OR (c = Class.Error) > OR ((c = Class.Packed) AND IsOrdinal (StripPacked (t))); > END IsOrdinal; > > > - Jay > > > > > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3devel at elegosoft.com > Subject: RE: [M3devel] latest longint file size diffs > Date: Sat, 9 Jan 2010 07:52:29 +0000 > > ok, yeah, it does bug me. > > With 8 bit integer, 16 bit longint. > > Let's replace 128 with 127 + 1. > > (127 + 1) > 127 > > either: > is true > or false > or raises an exception > > "Obviously" it should be true, but implementing that is..uncertain. > Though, again, it should really raise the exception before the comparison is made. > Maybe it does. > > Where (127 + 1L) > 127 > > is simply true, no controversy..except for the difference with 127 + 1. > > But Rodney said something..that mixed operations fall out of > assignability. Right?? > > > I have an idea..I mean..an obvious guess/experiment. > I can try providing only for bidirectional assignability > and see what the affect on rd/wr is. > Maybe bidirectional assignability is enough to > keep the diff small? > Or, maybe my initial big diff with ORD/VAL everywhere is acceptable? > Clearly it will be allowed by any of the proposals, it > just might not be necessary. > > > Also, btw, I think we should warn for truncating assignment. > Any time a range check is put in, perhaps. > Except maybe not on array indexing. > Which might leave this suggestion completely ambiguous as > to when a warning should be issued. > > But as has been pointed out, while it may be "annoying" and > "inconvenient" to put ORD and VAL everywhere, or at least ORD, > it does force us to revisit all those locations where a change > is being induced. > > Notice that that the warning may or may not be platform specific. > It might trigger only on 32bit platforms. > Or the compiler targeting 64bit platforms might "know" about > the truncation potential on other platforms and warn. > In a specific concrete way, assignment of LONGINT to INTEGER > might warn, no matter their current exact sizes. > > > Extending that rule to subranges might be tricky. > TYPE A = [0..LAST(INTEGER)/2]; > TYPE B = [0..LAST(LONGINT)/2]; > VAR a: A; b:B; > > a := b; warn? > > Implementing that, maybe, would require, like a bit carried along > with type definitions in the compiler, as to if the definition > contains a platform independent size in it...er.. > if the size is dependent on bitsize(integer) or not, and > mixing of that type with any? other type is a warning? > Clearly no. Mixing with a type dependent on bitsize(longint)? > Maybe. > > I'm not sure what the rule is, but, you know, it'd be nice > if above code did warn on 64bit targets, in order to > encourage portability to 32bit targets. > > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 07:01:47 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] latest longint file size diffs > > > (LAST(INTEGER) + 1) = FIRST(INTEGER) > > ps: a beginner wouldn't necessarily expect this. > He might expect an error or widening of precision as needed. > Eventually faced with the cruel realities of what can be efficiently implemented, > he might accept any of our answers. :) > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3devel at elegosoft.com > Subject: RE: [M3devel] latest longint file size diffs > Date: Sat, 9 Jan 2010 06:59:52 +0000 > > I'll admit to being a little unsure. > > > I do hope the rd/wr change can be done with a small diff, maybe nothing outside libm3. > > > You might classify me more as a lazy user than a language designing deep thinker. > > > But I'm curious even about your assertion. > > > Let's pretend INTEGER is 8 bits and LONGINT is 16 bits, ok? > It is easier for me. > > > INTEGER max := 16_7F; > INTEGER first := 16_80; > INTEGER p1 := max + 1; > LONGINT p1L := max + 1L; > > > So, what happens if we compare p1 with first and p1L with first? > Again remember INTEGER is 8 bits, LONGINT is 16 bits. > > p1 will be -128, 0x80. > p1L will be 128, 0x0080. > > > What then happens when you compare 0x0080 to 0x80? > Are they equal (truncate both to INTEGER and compare), unequal (sign extend to LONGINT and compare), or you get an exception (upon narrowing the LONGINT to INTEGER and it doesn't fit)? > > > And heck, shouldn't max + 1 already throw an exception? > > > - Jay > > > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 01:03:08 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] latest longint file size diffs > > On 9 Jan 2010, at 00:50, Jay K wrote: > > I don't know the precedence but agreed: > > > > OR (IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL)) > > OR (IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL))) > > I was being sort of lazy. > I've never touched the front end and it was critical I be able to make > a small change and see fairly precisely the expected change, even > if I didn't get all cases. > > This is I'm sure why I had to add some VAL/ORD uses, to convert "UINT32" > in the Win32 code to INTEGER or LONGINT. > > Yes, that would be why. > > Also, I really think mixed arithmetic is ok. > > But are you ok with: > > (LAST(INTEGER) + 1) = FIRST(INTEGER) > > while > > (LAST(INTEGER) + 1L) # FIRST(INTEGER) > > ? > > I find such things to be difficult to explain to the novice programmer. Modula-3 was designed using the "principle of least surprise" and I frankly find the above to be very surprising! > > > - Jay > > > > From: hosking at cs.purdue.edu > > Date: Sat, 9 Jan 2010 00:37:42 -0500 > > To: jay.krell at cornell.edu > > CC: m3devel at elegosoft.com > > Subject: Re: [M3devel] latest longint file size diffs > > > > Looking at your code, I think the assignability test for ordinals should be more like: > > > > IF (IsEqual (Base(a), Base(b), NIL) > > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > > AND GetBounds (a, min_a, max_a) > > AND GetBounds (b, min_b, max_b) THEN > > (* check for a non-empty intersection *) > > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > > RETURN TInt.LE (min, max); > > ELSE > > RETURN FALSE; > > END; > > > > That way CARDINAL and other subranges fall right out. > > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > > 305 N. University Street | West Lafayette | IN 47907 | USA > > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > > > > > > On 8 Jan 2010, at 06:13, Jay K wrote: > > > > > Attached is my latest work here. > > > With the compiler changes (in the diff), I was able to > > > elminate most uses of VAL(expr, LONGINT). > > > There's something slightly off such that I had > > > to add a very small number, like two. > > > > > > > > > The compiler change is newer than earlier. > > > For example you can now assign CARDINAL to LONGINT. > > > I didn't do it, but you should also be able to add/subtract/etc. > > > mixing CARDINAL and LONGINT. > > > > > > > > > FOR statements also don't allow the level of mixing > > > that they should. > > > > > > > > > I'm hoping to get agreement soon just from the diffs > > > but if necessary I'll look how to create a branch. > > > My general worry about branches is developers just > > > go off on their own in a branch and it's impossible to > > > get anyone to look at it, they are busy enough with one branch, > > > let alone multiple.. > > > > > > > > > - Jay > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 9 19:25:23 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 13:25:23 -0500 Subject: [M3devel] index array by longint? In-Reply-To: References: Message-ID: I think having assignability let's you do what you need. The range check on assignment will then allow you to index... On 9 Jan 2010, at 04:34, Jay K wrote: > Index array by longint? > With runtime check that it is <= LAST(INTEGER)? > Or really, with runtime bounds check against the array size. > > Seems reasonable? > Aids the rd/wr change. > A little bit of pain to implement..unless INTEGER and LONGINT have a common base... > > > - Jay > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 9 19:30:55 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 13:30:55 -0500 Subject: [M3devel] another longint variant In-Reply-To: References: Message-ID: <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu> Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... On 9 Jan 2010, at 05:22, Jay K wrote: > [attached] > In this variant, the compiler has been made > "maximally lenient" and the rd/wr changes are minimized. > > > Specifically: > compiler allows assignment either way and various math > operations, including NEW array and array subscript. > mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) > > > rd/wr changes outside libm3 are only changing > the signatures of Seek and Length > pretty minimal, and hard to imagine they could be smaller, > though actually they could..well..the need to fix existing > rd/wr could be eliminated/delayed > rd/wr could introduce SeekL, LengthL which by default > call Seek/Length, and then rd/wr could gradually convert, > and not gain 4GB capability until then > > > no VAL or ORD needed > > > some rd/wr implementations might be artificially limited > to 4G simply because they don't chane some INTEGER to LONGINT; > "anything compiles" > > > some of the compiler changes are probably slightly off or incomplete > including a need to insert the checks for LONGINT => INTEGER > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Jan 9 20:33:45 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 19:33:45 +0000 Subject: [M3devel] another longint variant In-Reply-To: <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu> References: , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu> Message-ID: I don't believe that suffices but I can check again. - Jay Subject: Re: [M3devel] another longint variant From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 13:30:55 -0500 CC: m3devel at elegosoft.com To: jay.krell at cornell.edu Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... On 9 Jan 2010, at 05:22, Jay K wrote: [attached] In this variant, the compiler has been made "maximally lenient" and the rd/wr changes are minimized. Specifically: compiler allows assignment either way and various math operations, including NEW array and array subscript. mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) rd/wr changes outside libm3 are only changing the signatures of Seek and Length pretty minimal, and hard to imagine they could be smaller, though actually they could..well..the need to fix existing rd/wr could be eliminated/delayed rd/wr could introduce SeekL, LengthL which by default call Seek/Length, and then rd/wr could gradually convert, and not gain 4GB capability until then no VAL or ORD needed some rd/wr implementations might be artificially limited to 4G simply because they don't chane some INTEGER to LONGINT; "anything compiles" some of the compiler changes are probably slightly off or incomplete including a need to insert the checks for LONGINT => INTEGER -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 9 20:52:19 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 14:52:19 -0500 Subject: [M3devel] another longint variant In-Reply-To: References: , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu> Message-ID: It should suffice for assignability... On 9 Jan 2010, at 14:33, Jay K wrote: > I don't believe that suffices but I can check again. > > - Jay > > > Subject: Re: [M3devel] another longint variant > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 13:30:55 -0500 > CC: m3devel at elegosoft.com > To: jay.krell at cornell.edu > > Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... > > On 9 Jan 2010, at 05:22, Jay K wrote: > > [attached] > In this variant, the compiler has been made > "maximally lenient" and the rd/wr changes are minimized. > > > Specifically: > compiler allows assignment either way and various math > operations, including NEW array and array subscript. > mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) > > > rd/wr changes outside libm3 are only changing > the signatures of Seek and Length > pretty minimal, and hard to imagine they could be smaller, > though actually they could..well..the need to fix existing > rd/wr could be eliminated/delayed > rd/wr could introduce SeekL, LengthL which by default > call Seek/Length, and then rd/wr could gradually convert, > and not gain 4GB capability until then > > > no VAL or ORD needed > > > some rd/wr implementations might be artificially limited > to 4G simply because they don't chane some INTEGER to LONGINT; > "anything compiles" > > > some of the compiler changes are probably slightly off or incomplete > including a need to insert the checks for LONGINT => INTEGER > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sat Jan 9 20:50:25 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 09 Jan 2010 13:50:25 -0600 Subject: [M3devel] Unbounded but finite LONGINT In-Reply-To: <99206B8B-5004-4D0C-966B-0CBC0D6A6AD8@cs.purdue.edu> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <20100108215028.40A651A207A@async.async.caltech.edu> <20100108230505.GC9749@topoi.pooq.com> <20100109013342.GA23519@topoi.pooq.com> <99206B8B-5004-4D0C-966B-0CBC0D6A6AD8@cs.purdue.edu> Message-ID: <4B48DE01.8040303@lcwb.coop> Tony Hosking wrote: > On 8 Jan 2010, at 20:33, hendrik at topoi.pooq.com > wrote: > >> On Fri, Jan 08, 2010 at 07:53:07PM -0500, Tony Hosking wrote: >>> I think what you are advocating is Rodney's proposal + assignability >>> of INTEGER and LONGINT + mixed arithmetic. >> >> I thought Rodney's propsal still had the compiler impose a bound on the >> size of LONGINT. Or did I miss something? > > Yes, it would. > >> I'm proposing to let the programmer use subranges of LONGINT that are as >> long as he wishes. And if the computer runs out of virtual memory to >> store one of the programmer's long integers, well, that's the computer >> imposing the limit, not the language. > > But there is still the question as to what *representation* is used to > decide the particular operation to apply. > > I suppose the compiler could choose a particular machine representation > based on the range of values in the subrange (much as it does currently). > But if you really want to have an arbitrary range type I would argue it > is much better to implement it as a library than as a primitive type. This I agree with wholeheartedly. Don't we already have some math libraries for things like this, or maybe rational arithmetic, etc? > > Just for fun, I suggest you take some time to watch the talk Growing a > Language, by Guy Steele > From jay.krell at cornell.edu Sat Jan 9 21:17:32 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 20:17:32 +0000 Subject: [M3devel] another longint variant In-Reply-To: References: , , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, , Message-ID: [replacing periods with semicolons to avoid truncation..] Right..I was going to say..as an overall change, like if we want mixed operations, it really doesn't suffice; Many of my m3front changes were in direct response to compilation errors and fixed them; I'm sure as well that just allowing assignability doesn't make the rd/wr change particuarly small/smooth. You need mixed operations, indexing, new, or else sprinkle ORD around; There's a particular characteristic I should point out in the rd/wr code; Maybe rd/wr should be modified..but it probably can't; In particular, my understanding of rd/wr is that the maintain two "numbers" (integer or longint, depending on how everything is resolved); These numbers indicate the file offset that is at the start of the buffer and at the end of the buffer. In a new world they need to be LONGINT; However their "span", their difference, describes an in-memory buffer size. Therefore their difference is always INTEGER or CARDINAL, not LONGINT. It'd be super cool, but probably not possible, if the language let you declare this somehow. THEN mixed operations and such wouldn't be needed, if the compiler new that subtracting these two integers yielded an INTEGER, and possibly inserted checks of that; But this is probably just a lazy user view and not realistic for the language. For assignability I think your change does work but mine was less wordy and maybe more general; The preexisting code allowed I believe any non-LONGINT ordinal type to be assigned to any non-LONGINT ordinal type if there are any overlapping values. Specifically really, non-ordinal types with same base type and anyoverlap. I removed the base type check; This makes enums <=> longint, integer subranges <=> longint, etc; - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 14:52:19 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] another longint variant It should suffice for assignability... On 9 Jan 2010, at 14:33, Jay K wrote: I don't believe that suffices but I can check again. - Jay Subject: Re: [M3devel] another longint variant From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 13:30:55 -0500 CC: m3devel at elegosoft.com To: jay.krell at cornell.edu Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... On 9 Jan 2010, at 05:22, Jay K wrote: [attached] In this variant, the compiler has been made "maximally lenient" and the rd/wr changes are minimized. Specifically: compiler allows assignment either way and various math operations, including NEW array and array subscript. mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) rd/wr changes outside libm3 are only changing the signatures of Seek and Length pretty minimal, and hard to imagine they could be smaller, though actually they could..well..the need to fix existing rd/wr could be eliminated/delayed rd/wr could introduce SeekL, LengthL which by default call Seek/Length, and then rd/wr could gradually convert, and not gain 4GB capability until then no VAL or ORD needed some rd/wr implementations might be artificially limited to 4G simply because they don't chane some INTEGER to LONGINT; "anything compiles" some of the compiler changes are probably slightly off or incomplete including a need to insert the checks for LONGINT => INTEGER -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sat Jan 9 21:20:32 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 20:20:32 +0000 Subject: [M3devel] Unbounded but finite LONGINT In-Reply-To: <4B48DE01.8040303@lcwb.coop> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com>,<4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <20100108215028.40A651A207A@async.async.caltech.edu> <20100108230505.GC9749@topoi.pooq.com> <20100109013342.GA23519@topoi.pooq.com>, <99206B8B-5004-4D0C-966B-0CBC0D6A6AD8@cs.purdue.edu>, <4B48DE01.8040303@lcwb.coop> Message-ID: Yes we have some such libraries; The "problem" is that libraries are inconvenient and in-fix operatores are convenient; You either need to: accept that and use what works or make the language amenable to more convenient libraries (i.e. provide for operator overloading in the language) or make more stuff "built in" / "special" We will probably just do the first. LONGINT will probably just always be exactly 64bits, no more, no less, and have the same overflow features as INTEGER; It'd be nifty for me if the frontend learned to do arbitrary precision integer arithmetic, because then NT386 would get a working LONGINT that way; But that's not a valid reason. :) - Jay > Date: Sat, 9 Jan 2010 13:50:25 -0600 > From: rodney_bates at lcwb.coop > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] Unbounded but finite LONGINT > > > > Tony Hosking wrote: > > On 8 Jan 2010, at 20:33, hendrik at topoi.pooq.com > > wrote: > > > >> On Fri, Jan 08, 2010 at 07:53:07PM -0500, Tony Hosking wrote: > >>> I think what you are advocating is Rodney's proposal + assignability > >>> of INTEGER and LONGINT + mixed arithmetic. > >> > >> I thought Rodney's propsal still had the compiler impose a bound on the > >> size of LONGINT. Or did I miss something? > > > > Yes, it would. > > > >> I'm proposing to let the programmer use subranges of LONGINT that are as > >> long as he wishes. And if the computer runs out of virtual memory to > >> store one of the programmer's long integers, well, that's the computer > >> imposing the limit, not the language. > > > > But there is still the question as to what *representation* is used to > > decide the particular operation to apply. > > > > I suppose the compiler could choose a particular machine representation > > based on the range of values in the subrange (much as it does currently). > > But if you really want to have an arbitrary range type I would argue it > > is much better to implement it as a library than as a primitive type. > > This I agree with wholeheartedly. Don't we already have some math libraries > for things like this, or maybe rational arithmetic, etc? > > > > > > Just for fun, I suggest you take some time to watch the talk Growing a > > Language, by Guy Steele > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 9 21:21:43 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 15:21:43 -0500 Subject: [M3devel] Unbounded but finite LONGINT In-Reply-To: <4B48DE01.8040303@lcwb.coop> References: <20100107164620.GA30061@topoi.pooq.com> <40F21639-B895-4FA1-9027-F781608F9BFC@cs.purdue.edu> <20100108040333.GB9556@topoi.pooq.com> <4B476704.8010403@lcwb.coop> <20100108190409.GF14151@topoi.pooq.com> <2733CF3C-639F-4DC7-85E6-624ED795BACC@cs.purdue.edu> <20100108213923.GA9749@topoi.pooq.com> <20100108215028.40A651A207A@async.async.caltech.edu> <20100108230505.GC9749@topoi.pooq.com> <20100109013342.GA23519@topoi.pooq.com> <99206B8B-5004-4D0C-966B-0CBC0D6A6AD8@cs.purdue.edu> <4B48DE01.8040303@lcwb.coop> Message-ID: On 9 Jan 2010, at 14:50, Rodney M. Bates wrote: > Tony Hosking wrote: >> On 8 Jan 2010, at 20:33, hendrik at topoi.pooq.com wrote: >>> On Fri, Jan 08, 2010 at 07:53:07PM -0500, Tony Hosking wrote: >>>> I think what you are advocating is Rodney's proposal + assignability >>>> of INTEGER and LONGINT + mixed arithmetic. >>> >>> I thought Rodney's propsal still had the compiler impose a bound on the >>> size of LONGINT. Or did I miss something? >> Yes, it would. >>> I'm proposing to let the programmer use subranges of LONGINT that are as >>> long as he wishes. And if the computer runs out of virtual memory to >>> store one of the programmer's long integers, well, that's the computer >>> imposing the limit, not the language. >> But there is still the question as to what *representation* is used to decide the particular operation to apply. >> I suppose the compiler could choose a particular machine representation based on the range of values in the subrange (much as it does currently). >> But if you really want to have an arbitrary range type I would argue it is much better to implement it as a library than as a primitive type. > > This I agree with wholeheartedly. Don't we already have some math libraries > for things like this, or maybe rational arithmetic, etc? Yes, the arithmetic package (m3-libs/arithmetic). From hosking at cs.purdue.edu Sat Jan 9 21:54:22 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 15:54:22 -0500 Subject: [M3devel] another longint variant In-Reply-To: References: , , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, , Message-ID: <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu> On 9 Jan 2010, at 15:17, Jay K wrote: > [replacing periods with semicolons to avoid truncation..] > > > Right..I was going to say..as an overall change, like if we > want mixed operations, it really doesn't suffice; > Many of my m3front changes were in direct response > to compilation errors and fixed them; I'd like precise examples. > I'm sure as well that just allowing assignability doesn't make the rd/wr > change particuarly small/smooth. You need mixed operations, > indexing, new, or else sprinkle ORD around; I'm not sure I see why sprinkling ORD is insufficient... again, precise examples. > There's a particular characteristic I should point out in the rd/wr code; > Maybe rd/wr should be modified..but it probably can't; > In particular, my understanding of rd/wr is that the maintain two > "numbers" (integer or longint, depending on how everything is resolved); > These numbers indicate the file offset that is at the start of the buffer > and at the end of the buffer. In a new world they need to be LONGINT; > However their "span", their difference, describes an > in-memory buffer size. Therefore their difference is always INTEGER > or CARDINAL, not LONGINT. It'd be super cool, but probably not > possible, if the language let you declare this somehow. > THEN mixed operations and such wouldn't be needed, > if the compiler new that subtracting these two integers > yielded an INTEGER, and possibly inserted checks of that; > But this is probably just a lazy user view and not realistic > for the language. That would be tricky... > For assignability I think your change does work but mine was less wordy > and maybe more general; No, yours breaks assignabilty from subrange to INTEGER/LONGINT. > The preexisting code allowed I believe any non-LONGINT ordinal > type to be assigned to any non-LONGINT ordinal type if there > are any overlapping values. Specifically really, > non-ordinal types with same base type and anyoverlap. > I removed the base type check; That's what broke it. > This makes enums <=> longint, integer subranges <=> longint, etc; Can I convince you to work things up with my trivial change? I really want to see the impact of not allowing mixed arithmetic while having assignability. > > - Jay > > > Subject: Re: [M3devel] another longint variant > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 13:30:55 -0500 > CC: m3devel at elegosoft.com > To: jay.krell at cornell.edu > > Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... > > On 9 Jan 2010, at 05:22, Jay K wrote: > > [attached] > In this variant, the compiler has been made > "maximally lenient" and the rd/wr changes are minimized. > > > Specifically: > compiler allows assignment either way and various math > operations, including NEW array and array subscript. > mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) > > > rd/wr changes outside libm3 are only changing > the signatures of Seek and Length > pretty minimal, and hard to imagine they could be smaller, > though actually they could..well..the need to fix existing > rd/wr could be eliminated/delayed > rd/wr could introduce SeekL, LengthL which by default > call Seek/Length, and then rd/wr could gradually convert, > and not gain 4GB capability until then > > > no VAL or ORD needed > > > some rd/wr implementations might be artificially limited > to 4G simply because they don't chane some INTEGER to LONGINT; > "anything compiles" > > > some of the compiler changes are probably slightly off or incomplete > including a need to insert the checks for LONGINT => INTEGER > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sat Jan 9 23:15:16 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 09 Jan 2010 16:15:16 -0600 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu> References: <4B476316.4000005@lcwb.coop> <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu> Message-ID: <4B48FFF4.8050307@lcwb.coop> Tony Hosking wrote: (excerpted) >........................................ >> 2. FIRST(LONGINT) <= FIRST(INTEGER) and LAST(INTEGER) <= LAST(LONGINT). > > Currently, direct comparison between LONGINT and INTEGER is not > permitted. If it were then this would be true. > I remember there was some vexing problem about what the result type should be for FIRST and LAST, but not the details. It seems to me now that the only thing that makes any sense is to preserve the existing rule that it is the base type of the argument type. This is really necessary to preserve existing semantics of the language and of existing code. This original proposal seems to be silent on the matter, which I suppose means I intended it as a NO CHANGE. I guess, if mixed relations are allowed, then I can't think of a problem with this. Even if mixed relations are disallowed, this range constraint could be expressed with explicit conversions, I suppose. ....................................................................... > >> 15. There is a new builtin type named LONGCARD. It "behaves just >> like" (but is not equal to) [0..LAST(LONGINT)]. >> >> The current CARDINAL has an interesting history. Originally, it >> was just a predefined name for the type [0..LAST(INTEGER)]. It >> was later changed to be "just like" the subrange, i.e., the two >> are not the same type, but have the same properties in every >> other respect. The only reason for the change had to do with >> reading pickles, which are completely defined and implemented as >> library code. The change did affect the type analysis of the >> language, nevertheless. >> >> We should preserve this property for LONGCARD too. > > Currently there is no implementation of LONGCARD. I argue that we don't > need LONGCARD (since, as discussed below, NUMBER should stay typed as > CARDINAL), unless LONGCARD is needed for pickles... Rodney? > LONGCARD is needed for pickles (and for no other reason, that I can think of). The problem is that if a record or object has a field of type [0..LAST(LONGCARD)], the actual value of LAST(LONGCARD) causes the type to be different on different target machines, making a pickle written on, say a 32-bit machine unreadable on a 64-bit machine. LONGCARD can be treated as the same type regardless of word size, allowing the automatic size changes pickles already does for INTEGER, CARDINAL, and LONGINT to extend to this subrange too. (Note: If you try to extend this size-changing by pickles to arbitrary subranges that use FIRST/LAST/NUMBER in their bounds expressions, you are jumping head first into a tar pit. I've thought about it just enough to conclude I wanted to step back.) ....................................................................... >> 20. The statement that the upperbound of a FOR loop should not be >> LAST(INTEGER) also applies to LAST(LONGINT). > > Agreed. > >> Note that the existing definition of FOR otherwise generalizes >> to LONGINT without change. > > The current implementation does not permit the range values to be > different types (both must be INTEGER or LONGINT), and the step value > must also match. Will we permit any mixing of values? If so, I assume > that we use the maximal type of the expressions (LONGINT if any one is > LONGINT, INTEGER otherwise). > I think allowing mixtures here is going too far. Moreover, the existing rule for FOR already requires the same base type for the two bounds, unlike the assignability rule for operators, so unless we change an existing language rule here, this form of mixing is not allowed. Note that the step value is "integer-valued" unconditionally, i.e., even if the bounds have, say, an enumeration type. Taken literally, I would say this would allow its type to be INTEGER, LONGINT, or any subrange thereof. Perhaps on a tiny 8-bit embedded processor, this could have a use. ...................................................................... >> 22. There is a new required interface LongWord. It almost exactly >> parallels Word, except 1) LongWord.T = LONGINT, and 2) it contains >> new functions ToWord and FromWord, that conversion between the two >> types, using unsigned interpretations of the values. ToInt may >> produce a checked runtime error, if the result value is not in the >> range of an unsigned interpretation of INTEGER. > > This is the current implementation, but we do not support ToWord and > FromWord. Why do we need these? All the operations in Word apply an unsigned interpretation to the bits of the word, whereas the operators and functions in the language apply signed. Unsigned expansion is different(zero extend) from signed (sign extend). FromWord would do the unsigned, while VAL would do the signed. Similarly, for contracting, the value range check is different. Signed means leftmost 33 bits all equal to each other. Unsigned means leftmost 32 are all zero. > >> Word.T = INTEGER, so LongWord.T should = LONGINT, for >> consistency. This means simple assignability tests and >> assignments between the types will use signed interpretations. >> So different functions are needed to do size changes with >> unsigned interpretation. > > This is the current implementation. > > From hosking at cs.purdue.edu Sat Jan 9 23:45:09 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 17:45:09 -0500 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: <4B48FFF4.8050307@lcwb.coop> References: <4B476316.4000005@lcwb.coop> <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu> <4B48FFF4.8050307@lcwb.coop> Message-ID: <73144E4F-24FF-4CD3-BEB7-D015720CD74C@cs.purdue.edu> Do you recall why CARDINAL is defined to behave like [0..LAST(INTEGER)] instead of [0..16_FFFFFFFF]? Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On 9 Jan 2010, at 17:15, Rodney M. Bates wrote: > > > Tony Hosking wrote: (excerpted) >> ........................................ >>> 2. FIRST(LONGINT) <= FIRST(INTEGER) and LAST(INTEGER) <= LAST(LONGINT). >> Currently, direct comparison between LONGINT and INTEGER is not permitted. If it were then this would be true. > > > I remember there was some vexing problem about what the result type > should be for FIRST and LAST, but not the details. It seems to > me now that the only thing that makes any sense is to preserve the > existing rule that it is the base type of the argument type. > This is really necessary to preserve existing semantics of the > language and of existing code. > > This original proposal seems to be silent on the matter, which I suppose > means I intended it as a NO CHANGE. I guess, if > mixed relations are allowed, then I can't think of a problem > with this. Even if mixed relations are disallowed, this range > constraint could be expressed with explicit conversions, I suppose. > > ....................................................................... > >>> 15. There is a new builtin type named LONGCARD. It "behaves just >>> like" (but is not equal to) [0..LAST(LONGINT)]. >>> >>> The current CARDINAL has an interesting history. Originally, it >>> was just a predefined name for the type [0..LAST(INTEGER)]. It >>> was later changed to be "just like" the subrange, i.e., the two >>> are not the same type, but have the same properties in every >>> other respect. The only reason for the change had to do with >>> reading pickles, which are completely defined and implemented as >>> library code. The change did affect the type analysis of the >>> language, nevertheless. >>> >>> We should preserve this property for LONGCARD too. >> Currently there is no implementation of LONGCARD. I argue that we don't need LONGCARD (since, as discussed below, NUMBER should stay typed as CARDINAL), unless LONGCARD is needed for pickles... Rodney? > > LONGCARD is needed for pickles (and for no other reason, that I can > think of). The problem is that if a record or object has a field of > type [0..LAST(LONGCARD)], the actual value of LAST(LONGCARD) causes > the type to be different on different target machines, making a pickle > written on, say a 32-bit machine unreadable on a 64-bit machine. > LONGCARD can be treated as the same type regardless of word size, > allowing the automatic size changes pickles already does for INTEGER, > CARDINAL, and LONGINT to extend to this subrange too. > > (Note: If you try to extend this size-changing by pickles to arbitrary > subranges that use FIRST/LAST/NUMBER in their bounds expressions, you > are jumping head first into a tar pit. I've thought about it just enough > to conclude I wanted to step back.) > > ....................................................................... > >>> 20. The statement that the upperbound of a FOR loop should not be >>> LAST(INTEGER) also applies to LAST(LONGINT). >> Agreed. >>> Note that the existing definition of FOR otherwise generalizes >>> to LONGINT without change. >> The current implementation does not permit the range values to be different types (both must be INTEGER or LONGINT), and the step value must also match. Will we permit any mixing of values? If so, I assume that we use the maximal type of the expressions (LONGINT if any one is LONGINT, INTEGER otherwise). >> > > I think allowing mixtures here is going too far. Moreover, the existing > rule for FOR already requires the same base type for the two bounds, unlike > the assignability rule for operators, so unless we change an existing > language rule here, this form of mixing is not allowed. > > Note that the step value is "integer-valued" unconditionally, i.e., > even if the bounds have, say, an enumeration type. Taken literally, I > would say this would allow its type to be INTEGER, LONGINT, or any subrange > thereof. Perhaps on a tiny 8-bit embedded processor, this could have > a use. > > ...................................................................... > > >>> 22. There is a new required interface LongWord. It almost exactly >>> parallels Word, except 1) LongWord.T = LONGINT, and 2) it contains >>> new functions ToWord and FromWord, that conversion between the two >>> types, using unsigned interpretations of the values. ToInt may >>> produce a checked runtime error, if the result value is not in the >>> range of an unsigned interpretation of INTEGER. >> This is the current implementation, but we do not support ToWord and FromWord. Why do we need these? > > All the operations in Word apply an unsigned interpretation to the bits > of the word, whereas the operators and functions in the language apply > signed. Unsigned expansion is different(zero extend) from signed (sign > extend). FromWord would do the unsigned, while VAL would do the signed. > > Similarly, for contracting, the value range check is different. Signed > means leftmost 33 bits all equal to each other. Unsigned means leftmost > 32 are all zero. > >>> Word.T = INTEGER, so LongWord.T should = LONGINT, for >>> consistency. This means simple assignability tests and >>> assignments between the types will use signed interpretations. >>> So different functions are needed to do size changes with >>> unsigned interpretation. >> This is the current implementation. >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Jan 9 23:48:05 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 17:48:05 -0500 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: <73144E4F-24FF-4CD3-BEB7-D015720CD74C@cs.purdue.edu> References: <4B476316.4000005@lcwb.coop> <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu> <4B48FFF4.8050307@lcwb.coop> <73144E4F-24FF-4CD3-BEB7-D015720CD74C@cs.purdue.edu> Message-ID: <337A4383-95A2-4767-8A9E-4C8EEE88B5AC@cs.purdue.edu> Actually, that doesn't make sense -- it is an empty subrange. On 9 Jan 2010, at 17:45, Tony Hosking wrote: > Do you recall why CARDINAL is defined to behave like [0..LAST(INTEGER)] instead of [0..16_FFFFFFFF]? > > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On 9 Jan 2010, at 17:15, Rodney M. Bates wrote: > >> >> >> Tony Hosking wrote: (excerpted) >>> ........................................ >>>> 2. FIRST(LONGINT) <= FIRST(INTEGER) and LAST(INTEGER) <= LAST(LONGINT). >>> Currently, direct comparison between LONGINT and INTEGER is not permitted. If it were then this would be true. >> >> >> I remember there was some vexing problem about what the result type >> should be for FIRST and LAST, but not the details. It seems to >> me now that the only thing that makes any sense is to preserve the >> existing rule that it is the base type of the argument type. >> This is really necessary to preserve existing semantics of the >> language and of existing code. >> >> This original proposal seems to be silent on the matter, which I suppose >> means I intended it as a NO CHANGE. I guess, if >> mixed relations are allowed, then I can't think of a problem >> with this. Even if mixed relations are disallowed, this range >> constraint could be expressed with explicit conversions, I suppose. >> >> ....................................................................... >> >>>> 15. There is a new builtin type named LONGCARD. It "behaves just >>>> like" (but is not equal to) [0..LAST(LONGINT)]. >>>> >>>> The current CARDINAL has an interesting history. Originally, it >>>> was just a predefined name for the type [0..LAST(INTEGER)]. It >>>> was later changed to be "just like" the subrange, i.e., the two >>>> are not the same type, but have the same properties in every >>>> other respect. The only reason for the change had to do with >>>> reading pickles, which are completely defined and implemented as >>>> library code. The change did affect the type analysis of the >>>> language, nevertheless. >>>> >>>> We should preserve this property for LONGCARD too. >>> Currently there is no implementation of LONGCARD. I argue that we don't need LONGCARD (since, as discussed below, NUMBER should stay typed as CARDINAL), unless LONGCARD is needed for pickles... Rodney? >> >> LONGCARD is needed for pickles (and for no other reason, that I can >> think of). The problem is that if a record or object has a field of >> type [0..LAST(LONGCARD)], the actual value of LAST(LONGCARD) causes >> the type to be different on different target machines, making a pickle >> written on, say a 32-bit machine unreadable on a 64-bit machine. >> LONGCARD can be treated as the same type regardless of word size, >> allowing the automatic size changes pickles already does for INTEGER, >> CARDINAL, and LONGINT to extend to this subrange too. >> >> (Note: If you try to extend this size-changing by pickles to arbitrary >> subranges that use FIRST/LAST/NUMBER in their bounds expressions, you >> are jumping head first into a tar pit. I've thought about it just enough >> to conclude I wanted to step back.) >> >> ....................................................................... >> >>>> 20. The statement that the upperbound of a FOR loop should not be >>>> LAST(INTEGER) also applies to LAST(LONGINT). >>> Agreed. >>>> Note that the existing definition of FOR otherwise generalizes >>>> to LONGINT without change. >>> The current implementation does not permit the range values to be different types (both must be INTEGER or LONGINT), and the step value must also match. Will we permit any mixing of values? If so, I assume that we use the maximal type of the expressions (LONGINT if any one is LONGINT, INTEGER otherwise). >>> >> >> I think allowing mixtures here is going too far. Moreover, the existing >> rule for FOR already requires the same base type for the two bounds, unlike >> the assignability rule for operators, so unless we change an existing >> language rule here, this form of mixing is not allowed. >> >> Note that the step value is "integer-valued" unconditionally, i.e., >> even if the bounds have, say, an enumeration type. Taken literally, I >> would say this would allow its type to be INTEGER, LONGINT, or any subrange >> thereof. Perhaps on a tiny 8-bit embedded processor, this could have >> a use. >> >> ...................................................................... >> >> >>>> 22. There is a new required interface LongWord. It almost exactly >>>> parallels Word, except 1) LongWord.T = LONGINT, and 2) it contains >>>> new functions ToWord and FromWord, that conversion between the two >>>> types, using unsigned interpretations of the values. ToInt may >>>> produce a checked runtime error, if the result value is not in the >>>> range of an unsigned interpretation of INTEGER. >>> This is the current implementation, but we do not support ToWord and FromWord. Why do we need these? >> >> All the operations in Word apply an unsigned interpretation to the bits >> of the word, whereas the operators and functions in the language apply >> signed. Unsigned expansion is different(zero extend) from signed (sign >> extend). FromWord would do the unsigned, while VAL would do the signed. >> >> Similarly, for contracting, the value range check is different. Signed >> means leftmost 33 bits all equal to each other. Unsigned means leftmost >> 32 are all zero. >> >>>> Word.T = INTEGER, so LongWord.T should = LONGINT, for >>>> consistency. This means simple assignability tests and >>>> assignments between the types will use signed interpretations. >>>> So different functions are needed to do size changes with >>>> unsigned interpretation. >>> This is the current implementation. >>> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 00:47:16 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 23:47:16 +0000 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: <73144E4F-24FF-4CD3-BEB7-D015720CD74C@cs.purdue.edu> References: <4B476316.4000005@lcwb.coop>, <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu>, <4B48FFF4.8050307@lcwb.coop>, <73144E4F-24FF-4CD3-BEB7-D015720CD74C@cs.purdue.edu> Message-ID: On a 32bit system, what is the difference? Obviously LAST(INTEGER) is different and probably more correct on 64bit. - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 17:45:09 -0500 To: rodney_bates at lcwb.coop CC: m3devel at elegosoft.com Subject: Re: [M3devel] LONGINT, my original proposal Do you recall why CARDINAL is defined to behave like [0..LAST(INTEGER)] instead of [0..16_FFFFFFFF]? Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On 9 Jan 2010, at 17:15, Rodney M. Bates wrote: Tony Hosking wrote: (excerpted) ........................................ 2. FIRST(LONGINT) <= FIRST(INTEGER) and LAST(INTEGER) <= LAST(LONGINT). Currently, direct comparison between LONGINT and INTEGER is not permitted. If it were then this would be true. I remember there was some vexing problem about what the result type should be for FIRST and LAST, but not the details. It seems to me now that the only thing that makes any sense is to preserve the existing rule that it is the base type of the argument type. This is really necessary to preserve existing semantics of the language and of existing code. This original proposal seems to be silent on the matter, which I suppose means I intended it as a NO CHANGE. I guess, if mixed relations are allowed, then I can't think of a problem with this. Even if mixed relations are disallowed, this range constraint could be expressed with explicit conversions, I suppose. ....................................................................... 15. There is a new builtin type named LONGCARD. It "behaves just like" (but is not equal to) [0..LAST(LONGINT)]. The current CARDINAL has an interesting history. Originally, it was just a predefined name for the type [0..LAST(INTEGER)]. It was later changed to be "just like" the subrange, i.e., the two are not the same type, but have the same properties in every other respect. The only reason for the change had to do with reading pickles, which are completely defined and implemented as library code. The change did affect the type analysis of the language, nevertheless. We should preserve this property for LONGCARD too. Currently there is no implementation of LONGCARD. I argue that we don't need LONGCARD (since, as discussed below, NUMBER should stay typed as CARDINAL), unless LONGCARD is needed for pickles... Rodney? LONGCARD is needed for pickles (and for no other reason, that I can think of). The problem is that if a record or object has a field of type [0..LAST(LONGCARD)], the actual value of LAST(LONGCARD) causes the type to be different on different target machines, making a pickle written on, say a 32-bit machine unreadable on a 64-bit machine. LONGCARD can be treated as the same type regardless of word size, allowing the automatic size changes pickles already does for INTEGER, CARDINAL, and LONGINT to extend to this subrange too. (Note: If you try to extend this size-changing by pickles to arbitrary subranges that use FIRST/LAST/NUMBER in their bounds expressions, you are jumping head first into a tar pit. I've thought about it just enough to conclude I wanted to step back.) ....................................................................... 20. The statement that the upperbound of a FOR loop should not be LAST(INTEGER) also applies to LAST(LONGINT). Agreed. Note that the existing definition of FOR otherwise generalizes to LONGINT without change. The current implementation does not permit the range values to be different types (both must be INTEGER or LONGINT), and the step value must also match. Will we permit any mixing of values? If so, I assume that we use the maximal type of the expressions (LONGINT if any one is LONGINT, INTEGER otherwise). I think allowing mixtures here is going too far. Moreover, the existing rule for FOR already requires the same base type for the two bounds, unlike the assignability rule for operators, so unless we change an existing language rule here, this form of mixing is not allowed. Note that the step value is "integer-valued" unconditionally, i.e., even if the bounds have, say, an enumeration type. Taken literally, I would say this would allow its type to be INTEGER, LONGINT, or any subrange thereof. Perhaps on a tiny 8-bit embedded processor, this could have a use. ...................................................................... 22. There is a new required interface LongWord. It almost exactly parallels Word, except 1) LongWord.T = LONGINT, and 2) it contains new functions ToWord and FromWord, that conversion between the two types, using unsigned interpretations of the values. ToInt may produce a checked runtime error, if the result value is not in the range of an unsigned interpretation of INTEGER. This is the current implementation, but we do not support ToWord and FromWord. Why do we need these? All the operations in Word apply an unsigned interpretation to the bits of the word, whereas the operators and functions in the language apply signed. Unsigned expansion is different(zero extend) from signed (sign extend). FromWord would do the unsigned, while VAL would do the signed. Similarly, for contracting, the value range check is different. Signed means leftmost 33 bits all equal to each other. Unsigned means leftmost 32 are all zero. Word.T = INTEGER, so LongWord.T should = LONGINT, for consistency. This means simple assignability tests and assignments between the types will use signed interpretations. So different functions are needed to do size changes with unsigned interpretation. This is the current implementation. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 00:48:41 2010 From: jay.krell at cornell.edu (Jay K) Date: Sat, 9 Jan 2010 23:48:41 +0000 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: <73144E4F-24FF-4CD3-BEB7-D015720CD74C@cs.purdue.edu> References: <4B476316.4000005@lcwb.coop>, <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu>, <4B48FFF4.8050307@lcwb.coop>, <73144E4F-24FF-4CD3-BEB7-D015720CD74C@cs.purdue.edu> Message-ID: Sorry, right, I read 16_FFFFFFFF as 16_7FFFFFFFF. Is this "not full range" thing we've been vaguly mentioning. Guessing, I think it is easier to define with the "half range". "All cardinals fit in integers" ? Something like that? No range check needed moving between them? - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu; rodney_bates at lcwb.coop CC: m3devel at elegosoft.com Subject: RE: [M3devel] LONGINT, my original proposal Date: Sat, 9 Jan 2010 23:47:16 +0000 On a 32bit system, what is the difference? Obviously LAST(INTEGER) is different and probably more correct on 64bit. - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 17:45:09 -0500 To: rodney_bates at lcwb.coop CC: m3devel at elegosoft.com Subject: Re: [M3devel] LONGINT, my original proposal Do you recall why CARDINAL is defined to behave like [0..LAST(INTEGER)] instead of [0..16_FFFFFFFF]? Antony Hosking | Associate Professor | Computer Science | Purdue University305 N. University Street | West Lafayette | IN 47907 | USAOffice +1 765 494 6001 | Mobile +1 765 427 5484 On 9 Jan 2010, at 17:15, Rodney M. Bates wrote: Tony Hosking wrote: (excerpted) ........................................ 2. FIRST(LONGINT) <= FIRST(INTEGER) and LAST(INTEGER) <= LAST(LONGINT). Currently, direct comparison between LONGINT and INTEGER is not permitted. If it were then this would be true. I remember there was some vexing problem about what the result type should be for FIRST and LAST, but not the details. It seems to me now that the only thing that makes any sense is to preserve the existing rule that it is the base type of the argument type. This is really necessary to preserve existing semantics of the language and of existing code. This original proposal seems to be silent on the matter, which I suppose means I intended it as a NO CHANGE. I guess, if mixed relations are allowed, then I can't think of a problem with this. Even if mixed relations are disallowed, this range constraint could be expressed with explicit conversions, I suppose. ....................................................................... 15. There is a new builtin type named LONGCARD. It "behaves just like" (but is not equal to) [0..LAST(LONGINT)]. The current CARDINAL has an interesting history. Originally, it was just a predefined name for the type [0..LAST(INTEGER)]. It was later changed to be "just like" the subrange, i.e., the two are not the same type, but have the same properties in every other respect. The only reason for the change had to do with reading pickles, which are completely defined and implemented as library code. The change did affect the type analysis of the language, nevertheless. We should preserve this property for LONGCARD too. Currently there is no implementation of LONGCARD. I argue that we don't need LONGCARD (since, as discussed below, NUMBER should stay typed as CARDINAL), unless LONGCARD is needed for pickles... Rodney? LONGCARD is needed for pickles (and for no other reason, that I can think of). The problem is that if a record or object has a field of type [0..LAST(LONGCARD)], the actual value of LAST(LONGCARD) causes the type to be different on different target machines, making a pickle written on, say a 32-bit machine unreadable on a 64-bit machine. LONGCARD can be treated as the same type regardless of word size, allowing the automatic size changes pickles already does for INTEGER, CARDINAL, and LONGINT to extend to this subrange too. (Note: If you try to extend this size-changing by pickles to arbitrary subranges that use FIRST/LAST/NUMBER in their bounds expressions, you are jumping head first into a tar pit. I've thought about it just enough to conclude I wanted to step back.) ....................................................................... 20. The statement that the upperbound of a FOR loop should not be LAST(INTEGER) also applies to LAST(LONGINT). Agreed. Note that the existing definition of FOR otherwise generalizes to LONGINT without change. The current implementation does not permit the range values to be different types (both must be INTEGER or LONGINT), and the step value must also match. Will we permit any mixing of values? If so, I assume that we use the maximal type of the expressions (LONGINT if any one is LONGINT, INTEGER otherwise). I think allowing mixtures here is going too far. Moreover, the existing rule for FOR already requires the same base type for the two bounds, unlike the assignability rule for operators, so unless we change an existing language rule here, this form of mixing is not allowed. Note that the step value is "integer-valued" unconditionally, i.e., even if the bounds have, say, an enumeration type. Taken literally, I would say this would allow its type to be INTEGER, LONGINT, or any subrange thereof. Perhaps on a tiny 8-bit embedded processor, this could have a use. ...................................................................... 22. There is a new required interface LongWord. It almost exactly parallels Word, except 1) LongWord.T = LONGINT, and 2) it contains new functions ToWord and FromWord, that conversion between the two types, using unsigned interpretations of the values. ToInt may produce a checked runtime error, if the result value is not in the range of an unsigned interpretation of INTEGER. This is the current implementation, but we do not support ToWord and FromWord. Why do we need these? All the operations in Word apply an unsigned interpretation to the bits of the word, whereas the operators and functions in the language apply signed. Unsigned expansion is different(zero extend) from signed (sign extend). FromWord would do the unsigned, while VAL would do the signed. Similarly, for contracting, the value range check is different. Signed means leftmost 33 bits all equal to each other. Unsigned means leftmost 32 are all zero. Word.T = INTEGER, so LongWord.T should = LONGINT, for consistency. This means simple assignability tests and assignments between the types will use signed interpretations. So different functions are needed to do size changes with unsigned interpretation. This is the current implementation. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 01:05:23 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 00:05:23 +0000 Subject: [M3devel] another longint variant In-Reply-To: <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu> References: , , , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, , , , , , <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu> Message-ID: Sorry something wasn't clear. If you just allow assignability, sprinkling ORD is sufficient, and must be done a lot, as presented in one of my diffs; Annoying, voluminous, but should suffice. I'll do it again if you need. With mixed operations and assignability, the only change outside libm3 is changing the signatures of Length and Seek and the FOR change, though that's just because I didn't really finish the mixed operation change. I just meant that assignability fix in the compiler doesn't suffice to actually enable mixed operations. I believe Rodney said something like "mixed operations follow from assignability"; and from a language point of view, that may be true, just not from the point of view; You know, if I can assign a LONGINT to an INTEGER, and then add it to an INTEGER; what is the difference vs. just allowing direct addition? VAR i1,i2:INTEGER; j1: LONGINT; i1 := j1; INC(i2, i1); vs. INC(i2, j1); If the first is allowed, shouldn't the second? - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 15:54:22 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] another longint variant On 9 Jan 2010, at 15:17, Jay K wrote:[replacing periods with semicolons to avoid truncation..] Right..I was going to say..as an overall change, like if we want mixed operations, it really doesn't suffice; Many of my m3front changes were in direct response to compilation errors and fixed them; I'd like precise examples. I'm sure as well that just allowing assignability doesn't make the rd/wr change particuarly small/smooth. You need mixed operations, indexing, new, or else sprinkle ORD around; I'm not sure I see why sprinkling ORD is insufficient... again, precise examples. There's a particular characteristic I should point out in the rd/wr code; Maybe rd/wr should be modified..but it probably can't; In particular, my understanding of rd/wr is that the maintain two "numbers" (integer or longint, depending on how everything is resolved); These numbers indicate the file offset that is at the start of the buffer and at the end of the buffer. In a new world they need to be LONGINT; However their "span", their difference, describes an in-memory buffer size. Therefore their difference is always INTEGER or CARDINAL, not LONGINT. It'd be super cool, but probably not possible, if the language let you declare this somehow. THEN mixed operations and such wouldn't be needed, if the compiler new that subtracting these two integers yielded an INTEGER, and possibly inserted checks of that; But this is probably just a lazy user view and not realistic for the language. That would be tricky... For assignability I think your change does work but mine was less wordy and maybe more general; No, yours breaks assignabilty from subrange to INTEGER/LONGINT. The preexisting code allowed I believe any non-LONGINT ordinal type to be assigned to any non-LONGINT ordinal type if there are any overlapping values. Specifically really, non-ordinal types with same base type and anyoverlap. I removed the base type check; That's what broke it. This makes enums <=> longint, integer subranges <=> longint, etc; Can I convince you to work things up with my trivial change? I really want to see the impact of not allowing mixed arithmetic while having assignability. - Jay Subject: Re: [M3devel] another longint variant From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 13:30:55 -0500 CC: m3devel at elegosoft.com To: jay.krell at cornell.edu Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... On 9 Jan 2010, at 05:22, Jay K wrote:[attached] In this variant, the compiler has been made "maximally lenient" and the rd/wr changes are minimized. Specifically: compiler allows assignment either way and various math operations, including NEW array and array subscript. mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) rd/wr changes outside libm3 are only changing the signatures of Seek and Length pretty minimal, and hard to imagine they could be smaller, though actually they could..well..the need to fix existing rd/wr could be eliminated/delayed rd/wr could introduce SeekL, LengthL which by default call Seek/Length, and then rd/wr could gradually convert, and not gain 4GB capability until then no VAL or ORD needed some rd/wr implementations might be artificially limited to 4G simply because they don't chane some INTEGER to LONGINT; "anything compiles" some of the compiler changes are probably slightly off or incomplete including a need to insert the checks for LONGINT => INTEGER -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 01:12:06 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 00:12:06 +0000 Subject: [M3devel] another longint variant In-Reply-To: References: ,,, , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, ,,, , , , , , , <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu>, Message-ID: > I believe Rodney said something like "mixed operations follow from assignability"; > and from a language point of view, that may be true, just not from the point of view; I meant to say, not from the language implementation point of view. Again, if I can assign and then add, might as well just allow add? Ditto assign and index, assign and multiply, etc. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 00:05:23 +0000 CC: m3devel at elegosoft.com Subject: Re: [M3devel] another longint variant Sorry something wasn't clear. If you just allow assignability, sprinkling ORD is sufficient, and must be done a lot, as presented in one of my diffs; Annoying, voluminous, but should suffice. I'll do it again if you need. With mixed operations and assignability, the only change outside libm3 is changing the signatures of Length and Seek and the FOR change, though that's just because I didn't really finish the mixed operation change. I just meant that assignability fix in the compiler doesn't suffice to actually enable mixed operations. I believe Rodney said something like "mixed operations follow from assignability"; and from a language point of view, that may be true, just not from the point of view; You know, if I can assign a LONGINT to an INTEGER, and then add it to an INTEGER; what is the difference vs. just allowing direct addition? VAR i1,i2:INTEGER; j1: LONGINT; i1 := j1; INC(i2, i1); vs. INC(i2, j1); If the first is allowed, shouldn't the second? - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 15:54:22 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] another longint variant On 9 Jan 2010, at 15:17, Jay K wrote:[replacing periods with semicolons to avoid truncation..] Right..I was going to say..as an overall change, like if we want mixed operations, it really doesn't suffice; Many of my m3front changes were in direct response to compilation errors and fixed them; I'd like precise examples. I'm sure as well that just allowing assignability doesn't make the rd/wr change particuarly small/smooth. You need mixed operations, indexing, new, or else sprinkle ORD around; I'm not sure I see why sprinkling ORD is insufficient... again, precise examples. There's a particular characteristic I should point out in the rd/wr code; Maybe rd/wr should be modified..but it probably can't; In particular, my understanding of rd/wr is that the maintain two "numbers" (integer or longint, depending on how everything is resolved); These numbers indicate the file offset that is at the start of the buffer and at the end of the buffer. In a new world they need to be LONGINT; However their "span", their difference, describes an in-memory buffer size. Therefore their difference is always INTEGER or CARDINAL, not LONGINT. It'd be super cool, but probably not possible, if the language let you declare this somehow. THEN mixed operations and such wouldn't be needed, if the compiler new that subtracting these two integers yielded an INTEGER, and possibly inserted checks of that; But this is probably just a lazy user view and not realistic for the language. That would be tricky... For assignability I think your change does work but mine was less wordy and maybe more general; No, yours breaks assignabilty from subrange to INTEGER/LONGINT. The preexisting code allowed I believe any non-LONGINT ordinal type to be assigned to any non-LONGINT ordinal type if there are any overlapping values. Specifically really, non-ordinal types with same base type and anyoverlap. I removed the base type check; That's what broke it. This makes enums <=> longint, integer subranges <=> longint, etc; Can I convince you to work things up with my trivial change? I really want to see the impact of not allowing mixed arithmetic while having assignability. - Jay Subject: Re: [M3devel] another longint variant From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 13:30:55 -0500 CC: m3devel at elegosoft.com To: jay.krell at cornell.edu Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... On 9 Jan 2010, at 05:22, Jay K wrote:[attached] In this variant, the compiler has been made "maximally lenient" and the rd/wr changes are minimized. Specifically: compiler allows assignment either way and various math operations, including NEW array and array subscript. mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) rd/wr changes outside libm3 are only changing the signatures of Seek and Length pretty minimal, and hard to imagine they could be smaller, though actually they could..well..the need to fix existing rd/wr could be eliminated/delayed rd/wr could introduce SeekL, LengthL which by default call Seek/Length, and then rd/wr could gradually convert, and not gain 4GB capability until then no VAL or ORD needed some rd/wr implementations might be artificially limited to 4G simply because they don't chane some INTEGER to LONGINT; "anything compiles" some of the compiler changes are probably slightly off or incomplete including a need to insert the checks for LONGINT => INTEGER -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 01:15:33 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 00:15:33 +0000 Subject: [M3devel] another longint variant In-Reply-To: References: ,,, , , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, , , , , , , , , , , , <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu>, Message-ID: Also, I would propose that AddExpr etc. could check if the types are assignable, and then allow the add, etc; However there is still the matter of chosing the return type, so maybe have to just do the complete check in each FooExpr.m3 file, not just delegate to IsAssignable; Possibly the return type could be "calculated", like as being the "larger" type in most cases, the "smaller" in a few. That way, e.g. if we add a third yet larger integer type, the code would just work; - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com Subject: RE: [M3devel] another longint variant Date: Sun, 10 Jan 2010 00:12:06 +0000 > I believe Rodney said something like "mixed operations follow from assignability"; > and from a language point of view, that may be true, just not from the point of view; I meant to say, not from the language implementation point of view. Again, if I can assign and then add, might as well just allow add? Ditto assign and index, assign and multiply, etc. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 00:05:23 +0000 CC: m3devel at elegosoft.com Subject: Re: [M3devel] another longint variant Sorry something wasn't clear. If you just allow assignability, sprinkling ORD is sufficient, and must be done a lot, as presented in one of my diffs; Annoying, voluminous, but should suffice. I'll do it again if you need. With mixed operations and assignability, the only change outside libm3 is changing the signatures of Length and Seek and the FOR change, though that's just because I didn't really finish the mixed operation change. I just meant that assignability fix in the compiler doesn't suffice to actually enable mixed operations. I believe Rodney said something like "mixed operations follow from assignability"; and from a language point of view, that may be true, just not from the point of view; You know, if I can assign a LONGINT to an INTEGER, and then add it to an INTEGER; what is the difference vs. just allowing direct addition? VAR i1,i2:INTEGER; j1: LONGINT; i1 := j1; INC(i2, i1); vs. INC(i2, j1); If the first is allowed, shouldn't the second? - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 15:54:22 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] another longint variant On 9 Jan 2010, at 15:17, Jay K wrote:[replacing periods with semicolons to avoid truncation..] Right..I was going to say..as an overall change, like if we want mixed operations, it really doesn't suffice; Many of my m3front changes were in direct response to compilation errors and fixed them; I'd like precise examples. I'm sure as well that just allowing assignability doesn't make the rd/wr change particuarly small/smooth. You need mixed operations, indexing, new, or else sprinkle ORD around; I'm not sure I see why sprinkling ORD is insufficient... again, precise examples. There's a particular characteristic I should point out in the rd/wr code; Maybe rd/wr should be modified..but it probably can't; In particular, my understanding of rd/wr is that the maintain two "numbers" (integer or longint, depending on how everything is resolved); These numbers indicate the file offset that is at the start of the buffer and at the end of the buffer. In a new world they need to be LONGINT; However their "span", their difference, describes an in-memory buffer size. Therefore their difference is always INTEGER or CARDINAL, not LONGINT. It'd be super cool, but probably not possible, if the language let you declare this somehow. THEN mixed operations and such wouldn't be needed, if the compiler new that subtracting these two integers yielded an INTEGER, and possibly inserted checks of that; But this is probably just a lazy user view and not realistic for the language. That would be tricky... For assignability I think your change does work but mine was less wordy and maybe more general; No, yours breaks assignabilty from subrange to INTEGER/LONGINT. The preexisting code allowed I believe any non-LONGINT ordinal type to be assigned to any non-LONGINT ordinal type if there are any overlapping values. Specifically really, non-ordinal types with same base type and anyoverlap. I removed the base type check; That's what broke it. This makes enums <=> longint, integer subranges <=> longint, etc; Can I convince you to work things up with my trivial change? I really want to see the impact of not allowing mixed arithmetic while having assignability. - Jay Subject: Re: [M3devel] another longint variant From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 13:30:55 -0500 CC: m3devel at elegosoft.com To: jay.krell at cornell.edu Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... On 9 Jan 2010, at 05:22, Jay K wrote:[attached] In this variant, the compiler has been made "maximally lenient" and the rd/wr changes are minimized. Specifically: compiler allows assignment either way and various math operations, including NEW array and array subscript. mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) rd/wr changes outside libm3 are only changing the signatures of Seek and Length pretty minimal, and hard to imagine they could be smaller, though actually they could..well..the need to fix existing rd/wr could be eliminated/delayed rd/wr could introduce SeekL, LengthL which by default call Seek/Length, and then rd/wr could gradually convert, and not gain 4GB capability until then no VAL or ORD needed some rd/wr implementations might be artificially limited to 4G simply because they don't chane some INTEGER to LONGINT; "anything compiles" some of the compiler changes are probably slightly off or incomplete including a need to insert the checks for LONGINT => INTEGER -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 01:21:38 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 19:21:38 -0500 Subject: [M3devel] another longint variant In-Reply-To: References: , , , , , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, , , , , , , , , , , , <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu>, Message-ID: On 9 Jan 2010, at 19:15, Jay K wrote: > Also, I would propose that AddExpr etc. could check if the types are assignable, and then allow the add, etc; > However there is still the matter of chosing the return type, so maybe have to just do the complete check in each > FooExpr.m3 file, not just delegate to IsAssignable; > Possibly the return type could be "calculated", like as being the "larger" type in most cases, > the "smaller" in a few. That way, e.g. if we add a third yet larger integer type, the code would just work; It is a bit of a stretch that we've even added LONGINT. So, don't get carried away thinking there'll be more. I'm in the middle of fixing some bugs in the range checking that were introduced when I added support for LONGINT. Its addition has turned out to be the source of some significant compiler bugs. > > - Jay > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3devel at elegosoft.com > Subject: RE: [M3devel] another longint variant > Date: Sun, 10 Jan 2010 00:12:06 +0000 > > > I believe Rodney said something like "mixed operations follow from assignability"; > > and from a language point of view, that may be true, just not from the point of view; > > I meant to say, not from the language implementation point of view. > > Again, if I can assign and then add, might as well just allow add? > Ditto assign and index, assign and multiply, etc. > > - Jay > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Sun, 10 Jan 2010 00:05:23 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] another longint variant > > Sorry something wasn't clear. > If you just allow assignability, sprinkling ORD is sufficient, and must be done a lot, as presented in one of my diffs; > Annoying, voluminous, but should suffice. > I'll do it again if you need. > > > With mixed operations and assignability, the only change outside libm3 is > changing the signatures of Length and Seek > and the FOR change, though that's just because I didn't really finish > the mixed operation change. > > > I just meant that assignability fix in the compiler doesn't suffice > to actually enable mixed operations. > > > I believe Rodney said something like "mixed operations follow from assignability"; > and from a language point of view, that may be true, just not from the point of view; > > > You know, if I can assign a LONGINT to an INTEGER, and then add it to an INTEGER; > what is the difference vs. just allowing direct addition? > > > VAR i1,i2:INTEGER; > j1: LONGINT; > > > i1 := j1; > INC(i2, i1); > > > vs. > INC(i2, j1); > > > If the first is allowed, shouldn't the second? > > > - Jay > > > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 15:54:22 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] another longint variant > > On 9 Jan 2010, at 15:17, Jay K wrote: > > [replacing periods with semicolons to avoid truncation..] > > > Right..I was going to say..as an overall change, like if we > want mixed operations, it really doesn't suffice; > Many of my m3front changes were in direct response > to compilation errors and fixed them; > > I'd like precise examples. > > I'm sure as well that just allowing assignability doesn't make the rd/wr > change particuarly small/smooth. You need mixed operations, > indexing, new, or else sprinkle ORD around; > > I'm not sure I see why sprinkling ORD is insufficient... again, precise examples. > > There's a particular characteristic I should point out in the rd/wr code; > Maybe rd/wr should be modified..but it probably can't; > In particular, my understanding of rd/wr is that the maintain two > "numbers" (integer or longint, depending on how everything is resolved); > These numbers indicate the file offset that is at the start of the buffer > and at the end of the buffer. In a new world they need to be LONGINT; > However their "span", their difference, describes an > in-memory buffer size. Therefore their difference is always INTEGER > or CARDINAL, not LONGINT. It'd be super cool, but probably not > possible, if the language let you declare this somehow. > THEN mixed operations and such wouldn't be needed, > if the compiler new that subtracting these two integers > yielded an INTEGER, and possibly inserted checks of that; > But this is probably just a lazy user view and not realistic > for the language. > > That would be tricky... > > For assignability I think your change does work but mine was less wordy > and maybe more general; > > No, yours breaks assignabilty from subrange to INTEGER/LONGINT. > > The preexisting code allowed I believe any non-LONGINT ordinal > type to be assigned to any non-LONGINT ordinal type if there > are any overlapping values. Specifically really, > non-ordinal types with same base type and anyoverlap. > I removed the base type check; > > That's what broke it. > > This makes enums <=> longint, integer subranges <=> longint, etc; > > Can I convince you to work things up with my trivial change? > > I really want to see the impact of not allowing mixed arithmetic while having assignability. > > > - Jay > > > Subject: Re: [M3devel] another longint variant > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 13:30:55 -0500 > CC: m3devel at elegosoft.com > To: jay.krell at cornell.edu > > Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... > > On 9 Jan 2010, at 05:22, Jay K wrote: > > [attached] > In this variant, the compiler has been made > "maximally lenient" and the rd/wr changes are minimized. > > > Specifically: > compiler allows assignment either way and various math > operations, including NEW array and array subscript. > mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) > > > rd/wr changes outside libm3 are only changing > the signatures of Seek and Length > pretty minimal, and hard to imagine they could be smaller, > though actually they could..well..the need to fix existing > rd/wr could be eliminated/delayed > rd/wr could introduce SeekL, LengthL which by default > call Seek/Length, and then rd/wr could gradually convert, > and not gain 4GB capability until then > > > no VAL or ORD needed > > > some rd/wr implementations might be artificially limited > to 4G simply because they don't chane some INTEGER to LONGINT; > "anything compiles" > > > some of the compiler changes are probably slightly off or incomplete > including a need to insert the checks for LONGINT => INTEGER > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mika at async.async.caltech.edu Sun Jan 10 01:25:52 2010 From: mika at async.async.caltech.edu (Mika Nystrom) Date: Sat, 09 Jan 2010 16:25:52 -0800 Subject: [M3devel] another longint variant In-Reply-To: References: , , , , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, , , , , , , , , , <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu>, Message-ID: <20100110002552.683AA1A2078@async.async.caltech.edu> Jay K writes: >--_953e6126-a89e-4966-8f22-5ccff92e7117_ >Content-Type: text/plain; charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable > > > > I believe Rodney said something like "mixed operations follow from assig= >nability"=3B > > and from a language point of view=2C that may be true=2C just not from t= >he point of view=3B > >I meant to say=2C not from the language implementation point of view. > >Again=2C if I can assign and then add=2C might as well just allow add? >Ditto assign and index=2C assign and multiply=2C etc. > The problem is that it's sometimes ambiguous what the result type is. If you want to get into this kind of mess, why don't you just program in C... I think this area is probably one of the reasons some people *like* Modula-3. We don't want to have to guess what an expression means... it should be obvious. If there are "promotion rules" it's just not that obvious. I'm reminded of one time when I was missing a prototype in a C program.............. ok that story could go on and on. Mika From jay.krell at cornell.edu Sun Jan 10 01:31:31 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 00:31:31 +0000 Subject: [M3devel] another longint variant In-Reply-To: References: , , , , ,,<69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, , , ,,, , , ,,, ,,, , , <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu>, , , , Message-ID: I noticed unary plus doesn't seem to be valid for LONGINT. That is fixed among my other diffs. I understand it matters little to take this "algorithmic" approach to determining if an AddExpr is valid. We haven't yet agreed it will even change from current, though I kind of think it would. Again, if I can assign LONGINT to INTEGER, and then add it, or vice versa, why not just allow the direct addition? Force the programmer through hoops so the code is much clearer? Or too verbose? - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 19:21:38 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] another longint variant On 9 Jan 2010, at 19:15, Jay K wrote:Also, I would propose that AddExpr etc. could check if the types are assignable, and then allow the add, etc; However there is still the matter of chosing the return type, so maybe have to just do the complete check in each FooExpr.m3 file, not just delegate to IsAssignable; Possibly the return type could be "calculated", like as being the "larger" type in most cases, the "smaller" in a few. That way, e.g. if we add a third yet larger integer type, the code would just work; It is a bit of a stretch that we've even added LONGINT. So, don't get carried away thinking there'll be more. I'm in the middle of fixing some bugs in the range checking that were introduced when I added support for LONGINT. Its addition has turned out to be the source of some significant compiler bugs. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu CC: m3devel at elegosoft.com Subject: RE: [M3devel] another longint variant Date: Sun, 10 Jan 2010 00:12:06 +0000 > I believe Rodney said something like "mixed operations follow from assignability"; > and from a language point of view, that may be true, just not from the point of view; I meant to say, not from the language implementation point of view. Again, if I can assign and then add, might as well just allow add? Ditto assign and index, assign and multiply, etc. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 00:05:23 +0000 CC: m3devel at elegosoft.com Subject: Re: [M3devel] another longint variant Sorry something wasn't clear. If you just allow assignability, sprinkling ORD is sufficient, and must be done a lot, as presented in one of my diffs; Annoying, voluminous, but should suffice. I'll do it again if you need. With mixed operations and assignability, the only change outside libm3 is changing the signatures of Length and Seek and the FOR change, though that's just because I didn't really finish the mixed operation change. I just meant that assignability fix in the compiler doesn't suffice to actually enable mixed operations. I believe Rodney said something like "mixed operations follow from assignability"; and from a language point of view, that may be true, just not from the point of view; You know, if I can assign a LONGINT to an INTEGER, and then add it to an INTEGER; what is the difference vs. just allowing direct addition? VAR i1,i2:INTEGER; j1: LONGINT; i1 := j1; INC(i2, i1); vs. INC(i2, j1); If the first is allowed, shouldn't the second? - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 15:54:22 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] another longint variant On 9 Jan 2010, at 15:17, Jay K wrote:[replacing periods with semicolons to avoid truncation..] Right..I was going to say..as an overall change, like if we want mixed operations, it really doesn't suffice; Many of my m3front changes were in direct response to compilation errors and fixed them; I'd like precise examples. I'm sure as well that just allowing assignability doesn't make the rd/wr change particuarly small/smooth. You need mixed operations, indexing, new, or else sprinkle ORD around; I'm not sure I see why sprinkling ORD is insufficient... again, precise examples. There's a particular characteristic I should point out in the rd/wr code; Maybe rd/wr should be modified..but it probably can't; In particular, my understanding of rd/wr is that the maintain two "numbers" (integer or longint, depending on how everything is resolved); These numbers indicate the file offset that is at the start of the buffer and at the end of the buffer. In a new world they need to be LONGINT; However their "span", their difference, describes an in-memory buffer size. Therefore their difference is always INTEGER or CARDINAL, not LONGINT. It'd be super cool, but probably not possible, if the language let you declare this somehow. THEN mixed operations and such wouldn't be needed, if the compiler new that subtracting these two integers yielded an INTEGER, and possibly inserted checks of that; But this is probably just a lazy user view and not realistic for the language. That would be tricky... For assignability I think your change does work but mine was less wordy and maybe more general; No, yours breaks assignabilty from subrange to INTEGER/LONGINT. The preexisting code allowed I believe any non-LONGINT ordinal type to be assigned to any non-LONGINT ordinal type if there are any overlapping values. Specifically really, non-ordinal types with same base type and anyoverlap. I removed the base type check; That's what broke it. This makes enums <=> longint, integer subranges <=> longint, etc; Can I convince you to work things up with my trivial change? I really want to see the impact of not allowing mixed arithmetic while having assignability. - Jay Subject: Re: [M3devel] another longint variant From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 13:30:55 -0500 CC: m3devel at elegosoft.com To: jay.krell at cornell.edu Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... On 9 Jan 2010, at 05:22, Jay K wrote:[attached] In this variant, the compiler has been made "maximally lenient" and the rd/wr changes are minimized. Specifically: compiler allows assignment either way and various math operations, including NEW array and array subscript. mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) rd/wr changes outside libm3 are only changing the signatures of Seek and Length pretty minimal, and hard to imagine they could be smaller, though actually they could..well..the need to fix existing rd/wr could be eliminated/delayed rd/wr could introduce SeekL, LengthL which by default call Seek/Length, and then rd/wr could gradually convert, and not gain 4GB capability until then no VAL or ORD needed some rd/wr implementations might be artificially limited to 4G simply because they don't chane some INTEGER to LONGINT; "anything compiles" some of the compiler changes are probably slightly off or incomplete including a need to insert the checks for LONGINT => INTEGER -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sun Jan 10 02:29:32 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 09 Jan 2010 19:29:32 -0600 Subject: [M3devel] latest longint file size diffs In-Reply-To: References: , , <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu>, , <98228FAE-31EB-43CA-83CB-58FE7323A964@cs.purdue.edu> Message-ID: <4B492D7C.9070800@lcwb.coop> Jay K wrote: > I'll admit to being a little unsure. > > > I do hope the rd/wr change can be done with a small diff, maybe nothing > outside libm3. > > > You might classify me more as a lazy user than a language designing deep > thinker. > > > But I'm curious even about your assertion. > > > Let's pretend INTEGER is 8 bits and LONGINT is 16 bits, ok? > It is easier for me. > > > INTEGER max := 16_7F; > INTEGER first := 16_80; > INTEGER p1 := max + 1; > LONGINT p1L := max + 1L; > > > So, what happens if we compare p1 with first and p1L with first? > Again remember INTEGER is 8 bits, LONGINT is 16 bits. > > p1 will be -128, 0x80. > p1L will be 128, 0x0080. > > > What then happens when you compare 0x0080 to 0x80? > Are they equal (truncate both to INTEGER and compare), unequal (sign > extend to LONGINT and compare), or you get an exception (upon narrowing > the LONGINT to INTEGER and it doesn't fit)? Whether mixed comparison is allowed or an explicit conversion is coded before comparing, the representation conversion of the value of p1 to LONGINT will do a sign extension, because INTEGER and LONGINT are both signed. Or rather, all the builtin operations apply signed interpretation. If instead, you converted p1 to LONGINT via the Long.FromWord I proposed, then it would be a zero extension. This can only be done explicitly. The comparison would always be done in 16 bits, unless you explicitly converted the LONGINT operand.down to 8 first. > > > And heck, shouldn't max + 1 already throw an exception? This is a separate issue. I have always been very skeptical about silently ignoring overflow. But all the questions about INTEGER and LONGINT really hinge only on the question of when does an overflow occur, not what happens when it does. > > > - Jay > > > ------------------------------------------------------------------------ > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 01:03:08 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] latest longint file size diffs > > On 9 Jan 2010, at 00:50, Jay K wrote: > > I don't know the precedence but agreed: > > > > OR (IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL)) > > OR (IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL))) > > I was being sort of lazy. > I've never touched the front end and it was critical I be able to make > a small change and see fairly precisely the expected change, even > if I didn't get all cases. > > This is I'm sure why I had to add some VAL/ORD uses, to convert "UINT32" > in the Win32 code to INTEGER or LONGINT. > > > Yes, that would be why. > > Also, I really think mixed arithmetic is ok. > > > But are you ok with: > > (LAST(INTEGER) + 1) = FIRST(INTEGER) > > while > > (LAST(INTEGER) + 1L) # FIRST(INTEGER) > > ? > > I find such things to be difficult to explain to the novice programmer. > Modula-3 was designed using the "principle of least surprise" and I > frankly find the above to be very surprising! > > > - Jay > > > > From: hosking at cs.purdue.edu > > Date: Sat, 9 Jan 2010 00:37:42 -0500 > > To: jay.krell at cornell.edu > > CC: m3devel at elegosoft.com > > Subject: Re: [M3devel] latest longint file size diffs > > > > Looking at your code, I think the assignability test for ordinals > should be more like: > > > > IF (IsEqual (Base(a), Base(b), NIL) > > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > > AND GetBounds (a, min_a, max_a) > > AND GetBounds (b, min_b, max_b) THEN > > (* check for a non-empty intersection *) > > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > > RETURN TInt.LE (min, max); > > ELSE > > RETURN FALSE; > > END; > > > > That way CARDINAL and other subranges fall right out. > > > > Antony Hosking | Associate Professor | Computer Science | Purdue > University > > 305 N. University Street | West Lafayette | IN 47907 | USA > > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > > > > > > On 8 Jan 2010, at 06:13, Jay K wrote: > > > > > Attached is my latest work here. > > > With the compiler changes (in the diff), I was able to > > > elminate most uses of VAL(expr, LONGINT). > > > There's something slightly off such that I had > > > to add a very small number, like two. > > > > > > > > > The compiler change is newer than earlier. > > > For example you can now assign CARDINAL to LONGINT. > > > I didn't do it, but you should also be able to add/subtract/etc. > > > mixing CARDINAL and LONGINT. > > > > > > > > > FOR statements also don't allow the level of mixing > > > that they should. > > > > > > > > > I'm hoping to get agreement soon just from the diffs > > > but if necessary I'll look how to create a branch. > > > My general worry about branches is developers just > > > go off on their own in a branch and it's impossible to > > > get anyone to look at it, they are busy enough with one branch, > > > let alone multiple.. > > > > > > > > > - Jay > > > > > > > From jay.krell at cornell.edu Sun Jan 10 03:05:24 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 02:05:24 +0000 Subject: [M3devel] IsAssignable Message-ID: Current: PROCEDURE IsAssignable (a, b: T): BOOLEAN = VAR i, e: T; min_a, max_a, min_b, max_b, min, max: Target.Int; BEGIN IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN RETURN TRUE; ELSIF IsOrdinal (a) THEN (* ordinal types: OK if there is a common supertype and they have at least one member in common. *) IF IsEqual (Base(a), Base(b), NIL) AND GetBounds (a, min_a, max_a) AND GetBounds (b, min_b, max_b) THEN (* check for a non-empty intersection *) min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; RETURN TInt.LE (min, max); ELSE RETURN FALSE; END; my proposed: PROCEDURE IsAssignable (a, b: T): BOOLEAN = VAR i, e: T; min_a, max_a, min_b, max_b, min, max: Target.Int; BEGIN IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN RETURN TRUE; ELSIF IsOrdinal (a) THEN (* ordinal types: OK if they have at least one member in common. *) IF GetBounds (a, min_a, max_a) AND GetBounds (b, min_b, max_b) THEN (* check for a non-empty intersection *) min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; RETURN TInt.LE (min, max); ELSE RETURN FALSE; END; Your proposed: > IF (IsEqual (Base(a), Base(b), NIL) > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > AND GetBounds (a, min_a, max_a) > AND GetBounds (b, min_b, max_b) THEN What's the point of checking the types? Given that they are both ordinal? To restrict certain assignments? Aren't the base types of any ordinal type either Int.T or LInt.T? So the check will always be true? I have to check. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney_bates at lcwb.coop Sun Jan 10 03:34:39 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 09 Jan 2010 20:34:39 -0600 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <20100108185453.GD14151@topoi.pooq.com> References: <20100107131117.GA22266@topoi.pooq.com> <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> <2E21F50B-4710-4123-BB1F-FDF77CDB8C59@cs.purdue.edu> <20100108114448.3fukoteb40og04og@mail.elegosoft.com> <20100108185453.GD14151@topoi.pooq.com> Message-ID: <4B493CBF.4080302@lcwb.coop> hendrik at topoi.pooq.com wrote: >> But let me ask a question. Is there ever any need for a Modula 3 > compiler to implement a type like 0..1024 as more than 16 bits? Even if > INTEGER is 32 bits? And: > Is it even necessary for a compiler to implement -128..127 as more than > one byte? And: >> One thing that is very much needed in a language (not the only thing) >> is a type that always matches the implementation's native arithmetic >> size, which is most efficient. If you don't distinguish this type, >> it becomes either impossible or horribly convoluted to define arithmetic >> so native machine arithmetic can be usually used where possible, >> but multi-word arithmetic will be used where needed. > > Yes. You do need this type. And you can even call it INTEGER. But is > there any reason it cannot be a predefined subrange type of LONGINT? When storing a value in a variable, the compiler can store subranges in fields just big enough to hold the value range, or somewhere between that size and the size of the base type. Sometimes, like -128..127, it probably should store it in a byte, and if the type is BITS 10 FOR 0..1023 and it's a field or array element, it must store in exactly 10 bits. But the question that creates trouble is not how many bits to store variables in, but how many bits to do arithmetic in. This affects when/whether overflows can occur. I define an overflow as a case where the mathematically correct value is, for whatever reason, not what you get. By "mathematically correct", I mean in the system of (unbounded) integers, not a modular arithmetic. The usual reason you don't get the correct value is that it won't fit in the field you are doing arithmetic in. What happens then is an orthogonal question. Is there an exception? Do we have a code like a NaN? Does it wrap modulo the word size? random bits? But our problems with INTEGER and LONGINT have only to do with when does an overflow happen. In Modula-3 and with only INTEGER and its subranges, the arithmetic is always done in the full range of INTEGER, even if the operands have subrange types. This follows from the facts that: 1) The language defines (for the + example) only + (x,y: INTEGER) : INTEGER, but not any + operations on any subrange(s) of INTEGER. 2) The operands of + have no parameter mode specified, which means the mode is VALUE. 3) The rule for VALUE mode is that the actual parameter need only be assignable to the formal, not necessarily of the same type. So if we have VAR a: [0..10]; VAR b: [20..30];, then the expression a+b is evaluated by effectively doing the assignments x:=a, y:=b to the formals x and y of +, before evaluating the +. At the machine level, the compiler will have to do a representation conversion of each subrange by expanding it to a full integer, then do the add on these, with an INTEGER result. And the range of INTEGER then determines when overflows occur. Moreover, a reasonable implementation will choose the range of INTEGER to match the native machine arithmetic of the target machine, which is the most efficient arithmetic available. This is about as near to tidy a way as possible to cope with the very untidy fact that computer arithmetic on what we call "integers" is different from the integers of mathematics. Now suppose we need a larger-than-native range arithmetic for selected purposes. If we try to do it by just having one integer type that is as large as anybody could want and then let programmers choose a subrange othat happens to match the target's native arithmetic, whenever that is enough range, it gets a lot uglier. Storing variables of this subrange in native words will work fine. But the size arithmetic is done in is the problem. The only way to preserve the relative tidiness of the system of subranges would be to have every subrange value's representation expanded to the largest size, then do the arithmetic in that size. But this loses the efficiency of native arithmetic on _every_ operation, something we just can't afford. So INTEGER has to have some special properties that arbitrary subranges do not, namely that it is a size arithmetic is done in, if neither operand has a larger range. Having two distinct base types is a lot cleaner and less misleading than trying to pretend that INTEGER is just a particular case of a subrange. This is messy. But it's about the best we can do, given the difference between efficient hardware "integer" arithmetic and the integer arithmetic of mathematics. Note that you can't fix this by trying to use the value range of where the final expression result is to be assigned/passed/whatever. Then the rules just get a whole lot more complicated (for programmer and compiler alike), and the cases where overflow can occur get a lot harder to anticipate. And the likelihood they are what is wanted is not good either. You might have a distant chance at this if an expression could have at most one operator, but multiple operators and intermediate results make it a tar pit. From hendrik at topoi.pooq.com Sun Jan 10 03:57:56 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Sat, 9 Jan 2010 21:57:56 -0500 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: <73144E4F-24FF-4CD3-BEB7-D015720CD74C@cs.purdue.edu> References: <4B476316.4000005@lcwb.coop> <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu> <4B48FFF4.8050307@lcwb.coop> <73144E4F-24FF-4CD3-BEB7-D015720CD74C@cs.purdue.edu> Message-ID: <20100110025755.GA17629@topoi.pooq.com> On Sat, Jan 09, 2010 at 05:45:09PM -0500, Tony Hosking wrote: > Do you recall why CARDINAL is defined to behave like > [0..LAST(INTEGER)] instead of [0..16_FFFFFFFF]? It's so that all CARDINALs are INTEGERs, presumably back when it was thought important to have only one base type on top of the type hierarchy. I've always thought that was a mistake. The simplest way to avoid that with LONGINT is to let programmers use only subranges of LONGINT, and to impose no limit on those subranges except for mamory capacity. This also means we don't have a FIRST(LONGINT) or a LAST(LONGINT) either. -- hendrik From rodney_bates at lcwb.coop Sun Jan 10 03:44:26 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 09 Jan 2010 20:44:26 -0600 Subject: [M3devel] latest longint file size diffs In-Reply-To: References: , , , , <1A6881F8-8DFE-4931-9BFC-1BB4DB7D3E5B@cs.purdue.edu>, , , , <98228FAE-31EB-43CA-83CB-58FE7323A964@cs.purdue.edu>, Message-ID: <4B493F0A.7030500@lcwb.coop> Jay K wrote: > Uh, maybe all ordinal types that overlap in any values are assignable? > Yes, exactly. From 2.3.1: "A type T is _assignable_ to a type U if: .. .. or T and U are ordinal types with at least one member in common." For an _expression_ to be assignable to T, some additional things must be checked, some of them at runtime. > > PROCEDURE IsAssignable (a, b: T): BOOLEAN = > VAR i, e: T; min_a, max_a, min_b, max_b, min, max: Target.Int; > BEGIN > IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN > RETURN TRUE; > ELSIF IsOrdinal (a) THEN > (* ordinal types: OK if they have at least one member in common. *) > IF GetBounds (a, min_a, max_a) > AND GetBounds (b, min_b, max_b) THEN > (* check for a non-empty intersection *) > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > RETURN TInt.LE (min, max); > ELSE > RETURN FALSE; > END; > ELSIF IsSubtype (a, b) THEN > (* may be ok, but must narrow rhs before doing the assignment *) > RETURN IsSubtype (b, Reff.T) > OR ArrayType.Split (b, i, e) > OR (IsSubtype (b, Addr.T) > AND (NOT Module.IsSafe() OR NOT IsEqual (b, Addr.T, NIL))); > ELSE > RETURN FALSE; > END; > END IsAssignable; > > > ? > I'll try it out. > > > What is an ordinal type?, I wonder, the compiler implementation: > > > PROCEDURE IsOrdinal (t: T): BOOLEAN = > VAR u := Check (t); c := u.info.class; > BEGIN > RETURN (c = Class.Integer) OR (c = Class.Longint) OR (c = > Class.Subrange) > OR (c = Class.Enum) OR (c = Class.Error) > OR ((c = Class.Packed) AND IsOrdinal (StripPacked (t))); > END IsOrdinal; > > > - Jay > > > > > > > ------------------------------------------------------------------------ > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3devel at elegosoft.com > Subject: RE: [M3devel] latest longint file size diffs > Date: Sat, 9 Jan 2010 07:52:29 +0000 > > ok, yeah, it does bug me. > > With 8 bit integer, 16 bit longint. > > Let's replace 128 with 127 + 1. > > (127 + 1) > 127 > > either: > is true > or false > or raises an exception > > "Obviously" it should be true, but implementing that is..uncertain. > Though, again, it should really raise the exception before the > comparison is made. > Maybe it does. > > Where (127 + 1L) > 127 > > is simply true, no controversy..except for the difference with 127 + 1. > > But Rodney said something..that mixed operations fall out of > assignability. Right?? > > > I have an idea..I mean..an obvious guess/experiment. > I can try providing only for bidirectional assignability > and see what the affect on rd/wr is. > Maybe bidirectional assignability is enough to > keep the diff small? > Or, maybe my initial big diff with ORD/VAL everywhere is acceptable? > Clearly it will be allowed by any of the proposals, it > just might not be necessary. > > > Also, btw, I think we should warn for truncating assignment. > Any time a range check is put in, perhaps. > Except maybe not on array indexing. > Which might leave this suggestion completely ambiguous as > to when a warning should be issued. > > But as has been pointed out, while it may be "annoying" and > "inconvenient" to put ORD and VAL everywhere, or at least ORD, > it does force us to revisit all those locations where a change > is being induced. > > Notice that that the warning may or may not be platform specific. > It might trigger only on 32bit platforms. > Or the compiler targeting 64bit platforms might "know" about > the truncation potential on other platforms and warn. > In a specific concrete way, assignment of LONGINT to INTEGER > might warn, no matter their current exact sizes. > > > Extending that rule to subranges might be tricky. > TYPE A = [0..LAST(INTEGER)/2]; > TYPE B = [0..LAST(LONGINT)/2]; > VAR a: A; b:B; > > a := b; warn? > > Implementing that, maybe, would require, like a bit carried along > with type definitions in the compiler, as to if the definition > contains a platform independent size in it...er.. > if the size is dependent on bitsize(integer) or not, and > mixing of that type with any? other type is a warning? > Clearly no. Mixing with a type dependent on bitsize(longint)? > Maybe. > > I'm not sure what the rule is, but, you know, it'd be nice > if above code did warn on 64bit targets, in order to > encourage portability to 32bit targets. > > > - Jay > > ------------------------------------------------------------------------ > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 07:01:47 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] latest longint file size diffs > > > (LAST(INTEGER) + 1) = FIRST(INTEGER) > > ps: a beginner wouldn't necessarily expect this. > He might expect an error or widening of precision as needed. > Eventually faced with the cruel realities of what can be efficiently > implemented, > he might accept any of our answers. :) > > - Jay > > ------------------------------------------------------------------------ > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3devel at elegosoft.com > Subject: RE: [M3devel] latest longint file size diffs > Date: Sat, 9 Jan 2010 06:59:52 +0000 > > I'll admit to being a little unsure. > > > I do hope the rd/wr change can be done with a small diff, maybe nothing > outside libm3. > > > You might classify me more as a lazy user than a language designing deep > thinker. > > > But I'm curious even about your assertion. > > > Let's pretend INTEGER is 8 bits and LONGINT is 16 bits, ok? > It is easier for me. > > > INTEGER max := 16_7F; > INTEGER first := 16_80; > INTEGER p1 := max + 1; > LONGINT p1L := max + 1L; > > > So, what happens if we compare p1 with first and p1L with first? > Again remember INTEGER is 8 bits, LONGINT is 16 bits. > > p1 will be -128, 0x80. > p1L will be 128, 0x0080. > > > What then happens when you compare 0x0080 to 0x80? > Are they equal (truncate both to INTEGER and compare), unequal (sign > extend to LONGINT and compare), or you get an exception (upon narrowing > the LONGINT to INTEGER and it doesn't fit)? > > > And heck, shouldn't max + 1 already throw an exception? > > > - Jay > > > ------------------------------------------------------------------------ > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 01:03:08 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] latest longint file size diffs > > On 9 Jan 2010, at 00:50, Jay K wrote: > > I don't know the precedence but agreed: > > > > OR (IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL)) > > OR (IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL))) > > I was being sort of lazy. > I've never touched the front end and it was critical I be able to make > a small change and see fairly precisely the expected change, even > if I didn't get all cases. > > This is I'm sure why I had to add some VAL/ORD uses, to convert "UINT32" > in the Win32 code to INTEGER or LONGINT. > > > Yes, that would be why. > > Also, I really think mixed arithmetic is ok. > > > But are you ok with: > > (LAST(INTEGER) + 1) = FIRST(INTEGER) > > while > > (LAST(INTEGER) + 1L) # FIRST(INTEGER) > > ? > > I find such things to be difficult to explain to the novice programmer. > Modula-3 was designed using the "principle of least surprise" and I > frankly find the above to be very surprising! > > > - Jay > > > > From: hosking at cs.purdue.edu > > Date: Sat, 9 Jan 2010 00:37:42 -0500 > > To: jay.krell at cornell.edu > > CC: m3devel at elegosoft.com > > Subject: Re: [M3devel] latest longint file size diffs > > > > Looking at your code, I think the assignability test for ordinals > should be more like: > > > > IF (IsEqual (Base(a), Base(b), NIL) > > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > > AND GetBounds (a, min_a, max_a) > > AND GetBounds (b, min_b, max_b) THEN > > (* check for a non-empty intersection *) > > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > > RETURN TInt.LE (min, max); > > ELSE > > RETURN FALSE; > > END; > > > > That way CARDINAL and other subranges fall right out. > > > > Antony Hosking | Associate Professor | Computer Science | Purdue > University > > 305 N. University Street | West Lafayette | IN 47907 | USA > > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > > > > > > On 8 Jan 2010, at 06:13, Jay K wrote: > > > > > Attached is my latest work here. > > > With the compiler changes (in the diff), I was able to > > > elminate most uses of VAL(expr, LONGINT). > > > There's something slightly off such that I had > > > to add a very small number, like two. > > > > > > > > > The compiler change is newer than earlier. > > > For example you can now assign CARDINAL to LONGINT. > > > I didn't do it, but you should also be able to add/subtract/etc. > > > mixing CARDINAL and LONGINT. > > > > > > > > > FOR statements also don't allow the level of mixing > > > that they should. > > > > > > > > > I'm hoping to get agreement soon just from the diffs > > > but if necessary I'll look how to create a branch. > > > My general worry about branches is developers just > > > go off on their own in a branch and it's impossible to > > > get anyone to look at it, they are busy enough with one branch, > > > let alone multiple.. > > > > > > > > > - Jay > > > > > > > From hendrik at topoi.pooq.com Sun Jan 10 04:04:13 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Sat, 9 Jan 2010 22:04:13 -0500 Subject: [M3devel] another longint variant In-Reply-To: References: <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu> Message-ID: <20100110030412.GB17629@topoi.pooq.com> On Sun, Jan 10, 2010 at 12:05:23AM +0000, Jay K wrote: > > I believe Rodney said something like "mixed operations follow from assignability"; > and from a language point of view, that may be true, just not from the point of view; > > > You know, if I can assign a LONGINT to an INTEGER, and then add it to an INTEGER; > what is the difference vs. just allowing direct addition? Let's add -16_080000003L to +16_7ffffffff. The sum should be 4. What you propose will give overflow when assigning LONGINT to INTEGER. You have to do the addition as LONGINT and then assign the sum to INTEGER. -- hendrik From hendrik at topoi.pooq.com Sun Jan 10 04:07:25 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Sat, 9 Jan 2010 22:07:25 -0500 Subject: [M3devel] another longint variant In-Reply-To: References: Message-ID: <20100110030725.GC17629@topoi.pooq.com> On Sat, Jan 09, 2010 at 07:21:38PM -0500, Tony Hosking wrote: > On 9 Jan 2010, at 19:15, Jay K wrote: > > > Also, I would propose that AddExpr etc. could check if the types are assignable, and then allow the add, etc; > > However there is still the matter of chosing the return type, so maybe have to just do the complete check in each > > FooExpr.m3 file, not just delegate to IsAssignable; > > Possibly the return type could be "calculated", like as being the "larger" type in most cases, > > the "smaller" in a few. That way, e.g. if we add a third yet larger integer type, the code would just work; > > It is a bit of a stretch that we've even added LONGINT. So, don't get > carried away thinking there'll be more. There will be more, sooner or later. Let's design for more, even if we don't implement it all right away. -- hendrik From rodney_bates at lcwb.coop Sun Jan 10 03:54:51 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sat, 09 Jan 2010 20:54:51 -0600 Subject: [M3devel] index array by longint? In-Reply-To: References: Message-ID: <4B49417B.7060806@lcwb.coop> When writing my original proposal, I agonized at length over whether to allow (subranges of) LONGINT to be the index type of an array type. In the end, I decided that gave a poor ratio of practical benefit to language and implementation complexity. However, note, from 2.6.3, "Designators, "a[i] denotes the (i + 1 - FIRST(a))-th element of the array a. The expression a[i] is a designator if a is, and is writable if a is. The expression i must be assignable --------------------------------------------------------------------------^ to the index type of a. The type of a[i] is the element type of a." So, by existing rules about assignability, when referring to an element of an array, the subscript expression could have base type LONGINT, and would just be "assigned" in the usual way to the index type, a subrange of INTEGER. This is one of the dozen or so places assignability is used in the language. Jay K wrote: > Index array by longint? > With runtime check that it is <= LAST(INTEGER)? > Or really, with runtime bounds check against the array size. > > Seems reasonable? > Aids the rd/wr change. > A little bit of pain to implement..unless INTEGER and LONGINT have a > common base... > > > - Jay > > > > > From hendrik at topoi.pooq.com Sun Jan 10 04:28:28 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Sat, 9 Jan 2010 22:28:28 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: <4B493CBF.4080302@lcwb.coop> References: <20100107131117.GA22266@topoi.pooq.com> <20100107145210.0ooessu9wg8k48co@mail.elegosoft.com> <2E21F50B-4710-4123-BB1F-FDF77CDB8C59@cs.purdue.edu> <20100108114448.3fukoteb40og04og@mail.elegosoft.com> <20100108185453.GD14151@topoi.pooq.com> <4B493CBF.4080302@lcwb.coop> Message-ID: <20100110032828.GD17629@topoi.pooq.com> On Sat, Jan 09, 2010 at 08:34:39PM -0600, Rodney M. Bates wrote: > > > But the question that creates trouble is not how many bits to store > variables > in, but how many bits to do arithmetic in. This affects when/whether > overflows > can occur. I define an overflow as a case where the mathematically correct > value is, for whatever reason, not what you get. By "mathematically > correct", I mean in the system of (unbounded) integers, not a modular > arithmetic. > The usual reason you don't get the correct value is that it won't fit in the > field you are doing arithmetic in. > > In Modula-3 and with only INTEGER and its subranges, the arithmetic is > always > done in the full range of INTEGER, even if the operands have subrange types. ... ... > > But the size arithmetic is done in is the problem. The only way to preserve > the relative tidiness of the system of subranges would be to have every > subrange value's representation expanded to the largest size, then do > the arithmetic in that size. But this loses the efficiency of native > arithmetic on _every_ operation, something we just can't afford. > > So INTEGER has to have some special properties that arbitrary subranges > do not, namely that it is a size arithmetic is done in, if neither operand > has a larger range. Having two distinct base types is a lot cleaner > and less misleading than trying to pretend that INTEGER is just a particular > case of a subrange. > > This is messy. But it's about the best we can do, given the difference > between efficient hardware "integer" arithmetic and the integer arithmetic > of mathematics. > > Note that you can't fix this by trying to use the value range of where the > final expression result is to be assigned/passed/whatever. Then the rules > just get a whole lot more complicated (for programmer and compiler alike), > and the cases where overflow can occur get a lot harder to anticipate. And > the > likelihood they are what is wanted is not good either. You might have a > distant chance at this if an expression could have at most one operator, > but multiple operators and intermediate results make it a tar pit. > > GOt that. INTEGER is not a subrange of LONGINT because its arithmetic is different. And the reason INTEGER has all its restrictions is simply to be able to use efficient machine arithmetic, and to make it clear that efficient machine arithmetic will be used. This is why we don't expand "every subrange value's representation ... to the largest size, then do the arithmetic in that size." But it is quite possible to performs operation on LONGINT subranges to produce results that are as long as necessary to be mathematically exact, because the whole point of LONGINT is to use it for numbers that do not fit the word size for the most efficient machine arithmetic. We're want to use subranges of LONGINT that match the requirements of an application, whether those subranges fit the most desirable machine word size or not. -- hendrik From hosking at cs.purdue.edu Sun Jan 10 05:12:22 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 23:12:22 -0500 Subject: [M3devel] IsAssignable In-Reply-To: References: Message-ID: Base type of an enumeration is itself! On 9 Jan 2010, at 21:05, Jay K wrote: > Current: > > > PROCEDURE IsAssignable (a, b: T): BOOLEAN = > VAR i, e: T; min_a, max_a, min_b, max_b, min, max: Target.Int; > BEGIN > IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN > RETURN TRUE; > ELSIF IsOrdinal (a) THEN > (* ordinal types: OK if there is a common supertype > and they have at least one member in common. *) > IF IsEqual (Base(a), Base(b), NIL) > AND GetBounds (a, min_a, max_a) > AND GetBounds (b, min_b, max_b) THEN > (* check for a non-empty intersection *) > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > RETURN TInt.LE (min, max); > ELSE > RETURN FALSE; > END; > > my proposed: > > > > PROCEDURE IsAssignable (a, b: T): BOOLEAN = > VAR i, e: T; min_a, max_a, min_b, max_b, min, max: Target.Int; > BEGIN > IF IsEqual (a, b, NIL) OR IsSubtype (b, a) THEN > RETURN TRUE; > ELSIF IsOrdinal (a) THEN > (* ordinal types: OK if they have at least one member in common. *) > IF GetBounds (a, min_a, max_a) > AND GetBounds (b, min_b, max_b) THEN > (* check for a non-empty intersection *) > min := min_a; IF TInt.LT (min, min_b) THEN min := min_b; END; > max := max_a; IF TInt.LT (max_b, max) THEN max := max_b; END; > RETURN TInt.LE (min, max); > ELSE > RETURN FALSE; > END; > > > Your proposed: > > > IF (IsEqual (Base(a), Base(b), NIL) > > OR IsEqual (Base(a), Int.T, NIL) AND IsEqual (Base(b), LInt.T, NIL) > > OR IsEqual (Base(a), LInt.T, NIL) AND IsEqual (Base(b), Int.T, NIL)) > > AND GetBounds (a, min_a, max_a) > > AND GetBounds (b, min_b, max_b) THEN > > What's the point of checking the types? Given that they are both ordinal? > To restrict certain assignments? > Aren't the base types of any ordinal type either Int.T or LInt.T? > So the check will always be true? > I have to check. > > > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 05:13:13 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 23:13:13 -0500 Subject: [M3devel] LONGINT, my original proposal In-Reply-To: <20100110025755.GA17629@topoi.pooq.com> References: <4B476316.4000005@lcwb.coop> <961DBA0B-87E8-4683-A9E1-CB8A84D802B9@cs.purdue.edu> <4B48FFF4.8050307@lcwb.coop> <73144E4F-24FF-4CD3-BEB7-D015720CD74C@cs.purdue.edu> <20100110025755.GA17629@topoi.pooq.com> Message-ID: <9CFA3CF7-98EE-430E-B0C3-8575FBF1A732@cs.purdue.edu> That is a drastic (and I think fatal) departure from the spirit of the language. On 9 Jan 2010, at 21:57, hendrik at topoi.pooq.com wrote: > On Sat, Jan 09, 2010 at 05:45:09PM -0500, Tony Hosking wrote: >> Do you recall why CARDINAL is defined to behave like >> [0..LAST(INTEGER)] instead of [0..16_FFFFFFFF]? > > It's so that all CARDINALs are INTEGERs, presumably back when it was > thought important to have only one base type on top of the type > hierarchy. I've always thought that was a mistake. > > The simplest way to avoid that with LONGINT is to let programmers use > only subranges of LONGINT, and to impose no limit on those subranges > except for mamory capacity. > > This also means we don't have a FIRST(LONGINT) or a LAST(LONGINT) > either. > > -- hendrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 05:14:57 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 23:14:57 -0500 Subject: [M3devel] another longint variant In-Reply-To: References: , , , , , , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, , , , , , , , , , , , , , , , <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu>, , , , Message-ID: <4440BF94-9372-4A3E-B0BF-03A5DFEA7E45@cs.purdue.edu> On 9 Jan 2010, at 19:31, Jay K wrote: > I noticed unary plus doesn't seem to be valid for LONGINT. > That is fixed among my other diffs. > > I understand it matters little to take this "algorithmic" approach to determining > if an AddExpr is valid. We haven't yet agreed it will even change from current, > though I kind of think it would. Again, if I can assign LONGINT to INTEGER, > and then add it, or vice versa, why not just allow the direct addition? > Force the programmer through hoops so the code is much clearer? Yes, clarity is important. > Or too verbose? Verbosity is sometimes valuable. It spells things out. > > - Jay > > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 19:21:38 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] another longint variant > > On 9 Jan 2010, at 19:15, Jay K wrote: > > Also, I would propose that AddExpr etc. could check if the types are assignable, and then allow the add, etc; > However there is still the matter of chosing the return type, so maybe have to just do the complete check in each > FooExpr.m3 file, not just delegate to IsAssignable; > Possibly the return type could be "calculated", like as being the "larger" type in most cases, > the "smaller" in a few. That way, e.g. if we add a third yet larger integer type, the code would just work; > > It is a bit of a stretch that we've even added LONGINT. So, don't get carried away thinking there'll be more. > > I'm in the middle of fixing some bugs in the range checking that were introduced when I added support for LONGINT. Its addition has turned out to be the source of some significant compiler bugs. > > > - Jay > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > CC: m3devel at elegosoft.com > Subject: RE: [M3devel] another longint variant > Date: Sun, 10 Jan 2010 00:12:06 +0000 > > > I believe Rodney said something like "mixed operations follow from assignability"; > > and from a language point of view, that may be true, just not from the point of view; > > I meant to say, not from the language implementation point of view. > > Again, if I can assign and then add, might as well just allow add? > Ditto assign and index, assign and multiply, etc. > > - Jay > > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Sun, 10 Jan 2010 00:05:23 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] another longint variant > > Sorry something wasn't clear. > If you just allow assignability, sprinkling ORD is sufficient, and must be done a lot, as presented in one of my diffs; > Annoying, voluminous, but should suffice. > I'll do it again if you need. > > > With mixed operations and assignability, the only change outside libm3 is > changing the signatures of Length and Seek > and the FOR change, though that's just because I didn't really finish > the mixed operation change. > > > I just meant that assignability fix in the compiler doesn't suffice > to actually enable mixed operations. > > > I believe Rodney said something like "mixed operations follow from assignability"; > and from a language point of view, that may be true, just not from the point of view; > > > You know, if I can assign a LONGINT to an INTEGER, and then add it to an INTEGER; > what is the difference vs. just allowing direct addition? > > > VAR i1,i2:INTEGER; > j1: LONGINT; > > > i1 := j1; > INC(i2, i1); > > > vs. > INC(i2, j1); > > > If the first is allowed, shouldn't the second? > > > - Jay > > > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 15:54:22 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] another longint variant > > On 9 Jan 2010, at 15:17, Jay K wrote: > > [replacing periods with semicolons to avoid truncation..] > > > Right..I was going to say..as an overall change, like if we > want mixed operations, it really doesn't suffice; > Many of my m3front changes were in direct response > to compilation errors and fixed them; > > I'd like precise examples. > > I'm sure as well that just allowing assignability doesn't make the rd/wr > change particuarly small/smooth. You need mixed operations, > indexing, new, or else sprinkle ORD around; > > I'm not sure I see why sprinkling ORD is insufficient... again, precise examples. > > There's a particular characteristic I should point out in the rd/wr code; > Maybe rd/wr should be modified..but it probably can't; > In particular, my understanding of rd/wr is that the maintain two > "numbers" (integer or longint, depending on how everything is resolved); > These numbers indicate the file offset that is at the start of the buffer > and at the end of the buffer. In a new world they need to be LONGINT; > However their "span", their difference, describes an > in-memory buffer size. Therefore their difference is always INTEGER > or CARDINAL, not LONGINT. It'd be super cool, but probably not > possible, if the language let you declare this somehow. > THEN mixed operations and such wouldn't be needed, > if the compiler new that subtracting these two integers > yielded an INTEGER, and possibly inserted checks of that; > But this is probably just a lazy user view and not realistic > for the language. > > That would be tricky... > > For assignability I think your change does work but mine was less wordy > and maybe more general; > > No, yours breaks assignabilty from subrange to INTEGER/LONGINT. > > The preexisting code allowed I believe any non-LONGINT ordinal > type to be assigned to any non-LONGINT ordinal type if there > are any overlapping values. Specifically really, > non-ordinal types with same base type and anyoverlap. > I removed the base type check; > > That's what broke it. > > This makes enums <=> longint, integer subranges <=> longint, etc; > > Can I convince you to work things up with my trivial change? > > I really want to see the impact of not allowing mixed arithmetic while having assignability. > > > - Jay > > > Subject: Re: [M3devel] another longint variant > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 13:30:55 -0500 > CC: m3devel at elegosoft.com > To: jay.krell at cornell.edu > > Jay, what are the implications of just having assignability rather than mixed arithmetic? Can you work through that change? My preference right now is to allow assignability (range-checked, of course) but not mixed arithmetic. The simple little patch I sent you for Type.IsAssignable on ordinals should allow you to test things. As far as I can tell, that will simply work... > > On 9 Jan 2010, at 05:22, Jay K wrote: > > [attached] > In this variant, the compiler has been made > "maximally lenient" and the rd/wr changes are minimized. > > > Specifically: > compiler allows assignment either way and various math > operations, including NEW array and array subscript. > mixing in FOR loops is missing (FOR i := INTEGER TO LONGINT or LONGINT TO INTEGER) > > > rd/wr changes outside libm3 are only changing > the signatures of Seek and Length > pretty minimal, and hard to imagine they could be smaller, > though actually they could..well..the need to fix existing > rd/wr could be eliminated/delayed > rd/wr could introduce SeekL, LengthL which by default > call Seek/Length, and then rd/wr could gradually convert, > and not gain 4GB capability until then > > > no VAL or ORD needed > > > some rd/wr implementations might be artificially limited > to 4G simply because they don't chane some INTEGER to LONGINT; > "anything compiles" > > > some of the compiler changes are probably slightly off or incomplete > including a need to insert the checks for LONGINT => INTEGER > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 05:16:37 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 23:16:37 -0500 Subject: [M3devel] another longint variant In-Reply-To: <20100110002552.683AA1A2078@async.async.caltech.edu> References: , , , , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, , , , , , , , , , <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu>, <20100110002552.683AA1A2078@async.async.caltech.edu> Message-ID: Hear, hear! On 9 Jan 2010, at 19:25, Mika Nystrom wrote: > Jay K writes: >> --_953e6126-a89e-4966-8f22-5ccff92e7117_ >> Content-Type: text/plain; charset="iso-8859-1" >> Content-Transfer-Encoding: quoted-printable >> >> >>> I believe Rodney said something like "mixed operations follow from assig= >> nability"=3B >>> and from a language point of view=2C that may be true=2C just not from t= >> he point of view=3B >> >> I meant to say=2C not from the language implementation point of view. >> >> Again=2C if I can assign and then add=2C might as well just allow add? >> Ditto assign and index=2C assign and multiply=2C etc. >> > > The problem is that it's sometimes ambiguous what the result type is. > > If you want to get into this kind of mess, why don't you just program in C... > > I think this area is probably one of the reasons some people *like* Modula-3. > We don't want to have to guess what an expression means... it should be obvious. > If there are "promotion rules" it's just not that obvious. I'm reminded of one > time when I was missing a prototype in a C program.............. ok that story > could go on and on. > > Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 05:22:44 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 23:22:44 -0500 Subject: [M3devel] index array by longint? In-Reply-To: <4B49417B.7060806@lcwb.coop> References: <4B49417B.7060806@lcwb.coop> Message-ID: <4F4DE877-9495-4E2D-910C-F55473E92F06@cs.purdue.edu> That's very nice! I like it. I think we can use it.... Right now I am tracking bugs in range checking. Some were introduced by my LONGINT changes (sigh!) but others appear to have been around a while before that. For example: VAR s: CARDINAL := LAST(INTEGER); BEGIN INC(s) END; did not result in a run-time error. I think I have fixed that now (commit to come). But, even worse: VAR s: CARDINAL := LAST(INTEGER); BEGIN WITH x = s DO x := VAL(ORD(x) + 1, CARDINAL) END END; also does not give a run-time error. The result is that you can store FIRST(INTEGER) in a CARDINAL. Yikes! On 9 Jan 2010, at 21:54, Rodney M. Bates wrote: > When writing my original proposal, I agonized at length over whether > to allow (subranges of) LONGINT to be the index type of an array type. In the > end, I decided that gave a poor ratio of practical benefit to language > and implementation complexity. > > However, note, from 2.6.3, "Designators, > > "a[i] > denotes the (i + 1 - FIRST(a))-th element of the array a. The expression a[i] is a > designator if a is, and is writable if a is. The expression i must be assignable > --------------------------------------------------------------------------^ > to the index type of a. The type of a[i] is the element type of a." > > So, by existing rules about assignability, when referring to an element of an > array, the subscript expression could have base type LONGINT, and would just > be "assigned" in the usual way to the index type, a subrange of INTEGER. > This is one of the dozen or so places assignability is used in the language. > > > > Jay K wrote: >> Index array by longint? >> With runtime check that it is <= LAST(INTEGER)? >> Or really, with runtime bounds check against the array size. >> Seems reasonable? >> Aids the rd/wr change. >> A little bit of pain to implement..unless INTEGER and LONGINT have a common base... >> - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 05:33:57 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 23:33:57 -0500 Subject: [M3devel] Integer overflow Message-ID: <2A81ABBC-A070-4857-86CF-AA16C7D4AE15@cs.purdue.edu> So, in my experiments with range checking on integers, I have been playing with the overflow case: VAR s: CARDINAL := LAST(INTEGER); BEGIN INC(s) END; Should this fail at runtime with a range check error? The language definition says that integer overflow may or may not be checked, depending on the implementation. (See FloatMode.i3). If it is not checked, is it reasonable that s takes on the value FIRST(INTEGER)? Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 05:38:42 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 23:38:42 -0500 Subject: [M3devel] Integer overflow In-Reply-To: <2A81ABBC-A070-4857-86CF-AA16C7D4AE15@cs.purdue.edu> References: <2A81ABBC-A070-4857-86CF-AA16C7D4AE15@cs.purdue.edu> Message-ID: One take on this is that it certainly lets you check for overflow explicitly! ;-) On the other hand, it seems unreasonable that you could end up with a CARDINAL holding a negative value! On 9 Jan 2010, at 23:33, Tony Hosking wrote: > So, in my experiments with range checking on integers, I have been playing with the overflow case: > > VAR s: CARDINAL := LAST(INTEGER); > BEGIN INC(s) END; > > Should this fail at runtime with a range check error? > > The language definition says that integer overflow may or may not be checked, depending on the implementation. (See FloatMode.i3). > > If it is not checked, is it reasonable that s takes on the value FIRST(INTEGER)? > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 05:42:18 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 04:42:18 +0000 Subject: [M3devel] index array by longint? In-Reply-To: <4F4DE877-9495-4E2D-910C-F55473E92F06@cs.purdue.edu> References: , <4B49417B.7060806@lcwb.coop>, <4F4DE877-9495-4E2D-910C-F55473E92F06@cs.purdue.edu> Message-ID: There are more cases: =, #, <, >, IN, etc. have this same "you can mix if they are assignable" rule. http://www.cs.purdue.edu/homes/hosking/m3/reference/relations.html infix =, # (x, y: Any): BOOLEAN The operator = returns TRUE if x and y are equal. The operator # returns TRUE if x and y are not equal. It is a static error if the type of x is not assignable to the type of y or vice versa. ... Other places demand equal types: http://www.cs.purdue.edu/homes/hosking/m3/reference/arithmetic.html inc/dec sound looser: http://www.cs.purdue.edu/homes/hosking/m3/reference/incdec.html I still think mixed operations are reasonable and the result types not so surprising. a := b; vs. a := b + c; The first is clear even if and b have different types, but the second is not, if b and c have different types? They seem pretty equally clear/unclear to me.. - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 23:22:44 -0500 To: rodney_bates at lcwb.coop CC: m3devel at elegosoft.com Subject: Re: [M3devel] index array by longint? That's very nice! I like it. I think we can use it....Right now I am tracking bugs in range checking. Some were introduced by my LONGINT changes (sigh!) but others appear to have been around a while before that. For example: VAR s: CARDINAL := LAST(INTEGER);BEGIN INC(s) END; did not result in a run-time error. I think I have fixed that now (commit to come). But, even worse: VAR s: CARDINAL := LAST(INTEGER);BEGIN WITH x = s DO x := VAL(ORD(x) + 1, CARDINAL) END END; also does not give a run-time error. The result is that you can store FIRST(INTEGER) in a CARDINAL. Yikes! On 9 Jan 2010, at 21:54, Rodney M. Bates wrote:When writing my original proposal, I agonized at length over whether to allow (subranges of) LONGINT to be the index type of an array type. In the end, I decided that gave a poor ratio of practical benefit to language and implementation complexity. However, note, from 2.6.3, "Designators, "a[i] denotes the (i + 1 - FIRST(a))-th element of the array a. The expression a[i] is a designator if a is, and is writable if a is. The expression i must be assignable --------------------------------------------------------------------------^ to the index type of a. The type of a[i] is the element type of a." So, by existing rules about assignability, when referring to an element of an array, the subscript expression could have base type LONGINT, and would just be "assigned" in the usual way to the index type, a subrange of INTEGER. This is one of the dozen or so places assignability is used in the language. Jay K wrote: Index array by longint? With runtime check that it is <= LAST(INTEGER)? Or really, with runtime bounds check against the array size. Seems reasonable? Aids the rd/wr change. A little bit of pain to implement..unless INTEGER and LONGINT have a common base... - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 05:45:29 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 23:45:29 -0500 Subject: [M3devel] Integer overflow In-Reply-To: <2A81ABBC-A070-4857-86CF-AA16C7D4AE15@cs.purdue.edu> References: <2A81ABBC-A070-4857-86CF-AA16C7D4AE15@cs.purdue.edu> Message-ID: <3F29FE3F-617D-493E-B687-C53B9D30D6C3@cs.purdue.edu> Even under the interpretation for INC that yields: VAR s: CARDINAL := LAST(INTEGER); BEGIN WITH x = s DO x := VAL(ORD(x) + 1, CARDINAL) END; END; the compiler currently does not insert a bounds check, because it reasons that the bound for ORD(x) + 1 is [0+1, LAST(INTEGER)], so the result is always assignable to CARDINAL. In reality, the compiler should presumably assume that because ORD(x) + 1 might overflow if ORD(x) = LAST(INTEGER) then the bound for the expression ORD(x)+1 is actually the same as INTEGER: [FIRST(INTEGER),LAST(INTEGER)]. So, because this is larger than the range for CARDINAL it really needs to insert a bounds check on the conversion to CARDINAL. On 9 Jan 2010, at 23:33, Tony Hosking wrote: > So, in my experiments with range checking on integers, I have been playing with the overflow case: > > VAR s: CARDINAL := LAST(INTEGER); > BEGIN INC(s) END; > > Should this fail at runtime with a range check error? > > The language definition says that integer overflow may or may not be checked, depending on the implementation. (See FloatMode.i3). > > If it is not checked, is it reasonable that s takes on the value FIRST(INTEGER)? > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > From hosking at cs.purdue.edu Sun Jan 10 05:46:39 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 9 Jan 2010 23:46:39 -0500 Subject: [M3devel] index array by longint? In-Reply-To: References: , <4B49417B.7060806@lcwb.coop>, <4F4DE877-9495-4E2D-910C-F55473E92F06@cs.purdue.edu> Message-ID: <2B01D3D0-70D5-4DDD-8778-965325B18588@cs.purdue.edu> I have a feeling that the mixed arithmetic option is losing favor. It is a slippery slope to C madness. On 9 Jan 2010, at 23:42, Jay K wrote: > There are more cases: > > =, #, <, >, IN, etc. have this same "you can mix > if they are assignable" rule. > > http://www.cs.purdue.edu/homes/hosking/m3/reference/relations.html > > infix =, # (x, y: Any): BOOLEAN > The operator = returns TRUE if x and y are equal. The operator # returns TRUE if x and y are not equal. It is a static error if the type of x is not assignable to the type of y or vice versa. > ... > > > Other places demand equal types: > http://www.cs.purdue.edu/homes/hosking/m3/reference/arithmetic.html > > inc/dec sound looser: > http://www.cs.purdue.edu/homes/hosking/m3/reference/incdec.html > > > I still think mixed operations are reasonable and the result types not so surprising. > a := b; > > vs. a := b + c; > > The first is clear even if and b have different types, but the second is not, if b and c have different types? > They seem pretty equally clear/unclear to me.. > > > - Jay > > > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 23:22:44 -0500 > To: rodney_bates at lcwb.coop > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] index array by longint? > > That's very nice! I like it. I think we can use it.... > > Right now I am tracking bugs in range checking. Some were introduced by my LONGINT changes (sigh!) but others appear to have been around a while before that. > > For example: > > VAR s: CARDINAL := LAST(INTEGER); > BEGIN INC(s) END; > > did not result in a run-time error. I think I have fixed that now (commit to come). > > But, even worse: > > VAR s: CARDINAL := LAST(INTEGER); > BEGIN WITH x = s DO x := VAL(ORD(x) + 1, CARDINAL) END END; > > also does not give a run-time error. > > The result is that you can store FIRST(INTEGER) in a CARDINAL. Yikes! > > On 9 Jan 2010, at 21:54, Rodney M. Bates wrote: > > When writing my original proposal, I agonized at length over whether > to allow (subranges of) LONGINT to be the index type of an array type. In the > end, I decided that gave a poor ratio of practical benefit to language > and implementation complexity. > > However, note, from 2.6.3, "Designators, > > "a[i] > denotes the (i + 1 - FIRST(a))-th element of the array a. The expression a[i] is a > designator if a is, and is writable if a is. The expression i must be assignable > --------------------------------------------------------------------------^ > to the index type of a. The type of a[i] is the element type of a." > > So, by existing rules about assignability, when referring to an element of an > array, the subscript expression could have base type LONGINT, and would just > be "assigned" in the usual way to the index type, a subrange of INTEGER. > This is one of the dozen or so places assignability is used in the language. > > > > Jay K wrote: > Index array by longint? > With runtime check that it is <= LAST(INTEGER)? > Or really, with runtime bounds check against the array size. > Seems reasonable? > Aids the rd/wr change. > A little bit of pain to implement..unless INTEGER and LONGINT have a common base... > - Jay > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 07:11:18 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 06:11:18 +0000 Subject: [M3devel] index array by longint? In-Reply-To: <2B01D3D0-70D5-4DDD-8778-965325B18588@cs.purdue.edu> References: , <4B49417B.7060806@lcwb.coop>, <4F4DE877-9495-4E2D-910C-F55473E92F06@cs.purdue.edu> , <2B01D3D0-70D5-4DDD-8778-965325B18588@cs.purdue.edu> Message-ID: I don't think there is madness here. I believe the half range of CARDINAL helps avoid it. A confusing point in C is comparison that includes conversion is magnitude or sign preserving -- comparing int and unsigned. Back to Modula-3: a := b; c := a + d; vs. c := b + d; are different? Isn't that strange? Compare with a : = b; c := d[a]; and c := d[b]; we have decided they are the same, among others. There's something about "kinda sorta transitive" here. Or, like, "why should I have to move values through temporaries in some cases but not others?" - Jay Subject: Re: [M3devel] index array by longint? From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 23:46:39 -0500 CC: rodney_bates at lcwb.coop; m3devel at elegosoft.com To: jay.krell at cornell.edu I have a feeling that the mixed arithmetic option is losing favor. It is a slippery slope to C madness. On 9 Jan 2010, at 23:42, Jay K wrote:There are more cases: =, #, <, >, IN, etc. have this same "you can mix if they are assignable" rule. http://www.cs.purdue.edu/homes/hosking/m3/reference/relations.html infix =, # (x, y: Any): BOOLEAN The operator = returns TRUE if x and y are equal. The operator # returns TRUE if x and y are not equal. It is a static error if the type of x is not assignable to the type of y or vice versa. ... Other places demand equal types: http://www.cs.purdue.edu/homes/hosking/m3/reference/arithmetic.html inc/dec sound looser: http://www.cs.purdue.edu/homes/hosking/m3/reference/incdec.html I still think mixed operations are reasonable and the result types not so surprising. a := b; vs. a := b + c; The first is clear even if and b have different types, but the second is not, if b and c have different types? They seem pretty equally clear/unclear to me.. - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 23:22:44 -0500 To: rodney_bates at lcwb.coop CC: m3devel at elegosoft.com Subject: Re: [M3devel] index array by longint? That's very nice! I like it. I think we can use it....Right now I am tracking bugs in range checking. Some were introduced by my LONGINT changes (sigh!) but others appear to have been around a while before that. For example: VAR s: CARDINAL := LAST(INTEGER);BEGIN INC(s) END; did not result in a run-time error. I think I have fixed that now (commit to come). But, even worse: VAR s: CARDINAL := LAST(INTEGER);BEGIN WITH x = s DO x := VAL(ORD(x) + 1, CARDINAL) END END; also does not give a run-time error. The result is that you can store FIRST(INTEGER) in a CARDINAL. Yikes! On 9 Jan 2010, at 21:54, Rodney M. Bates wrote:When writing my original proposal, I agonized at length over whether to allow (subranges of) LONGINT to be the index type of an array type. In the end, I decided that gave a poor ratio of practical benefit to language and implementation complexity. However, note, from 2.6.3, "Designators, "a[i] denotes the (i + 1 - FIRST(a))-th element of the array a. The expression a[i] is a designator if a is, and is writable if a is. The expression i must be assignable --------------------------------------------------------------------------^ to the index type of a. The type of a[i] is the element type of a." So, by existing rules about assignability, when referring to an element of an array, the subscript expression could have base type LONGINT, and would just be "assigned" in the usual way to the index type, a subrange of INTEGER. This is one of the dozen or so places assignability is used in the language. Jay K wrote: Index array by longint? With runtime check that it is <= LAST(INTEGER)? Or really, with runtime bounds check against the array size. Seems reasonable? Aids the rd/wr change. A little bit of pain to implement..unless INTEGER and LONGINT have a common base... - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 08:37:45 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sun, 10 Jan 2010 02:37:45 -0500 Subject: [M3devel] index array by longint? In-Reply-To: References: , <4B49417B.7060806@lcwb.coop>, <4F4DE877-9495-4E2D-910C-F55473E92F06@cs.purdue.edu> , <2B01D3D0-70D5-4DDD-8778-965325B18588@cs.purdue.edu> Message-ID: <3D1F9FE5-412E-4F2F-9C6F-89DDA439D70F@cs.purdue.edu> Try to frame this in terms of assignability... If the operators themselves were typed then there would be no problem. But when they aren't we get into a real mess trying to remember what the promotion rules are. On 10 Jan 2010, at 01:11, Jay K wrote: > I don't think there is madness here. > I believe the half range of CARDINAL helps avoid it. > A confusing point in C is comparison that includes conversion > is magnitude or sign preserving -- comparing int and unsigned. > > Back to Modula-3: > > a := b; > c := a + d; > > vs. > > c := b + d; > > > are different? > Isn't that strange? > > > Compare with > a : = b; > c := d[a]; > > and > > c := d[b]; > > we have decided they are the same, among others. > > > There's something about "kinda sorta transitive" here. > Or, like, "why should I have to move values through temporaries in some > cases but not others?" > > - Jay > > > > Subject: Re: [M3devel] index array by longint? > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 23:46:39 -0500 > CC: rodney_bates at lcwb.coop; m3devel at elegosoft.com > To: jay.krell at cornell.edu > > I have a feeling that the mixed arithmetic option is losing favor. It is a slippery slope to C madness. > > On 9 Jan 2010, at 23:42, Jay K wrote: > > There are more cases: > > =, #, <, >, IN, etc. have this same "you can mix > if they are assignable" rule. > > http://www.cs.purdue.edu/homes/hosking/m3/reference/relations.html > > infix =, # (x, y: Any): BOOLEAN > The operator = returns TRUE if x and y are equal. The operator # returns TRUE if x and y are not equal. It is a static error if the type of x is not assignable to the type of y or vice versa. > ... > > > Other places demand equal types: > http://www.cs.purdue.edu/homes/hosking/m3/reference/arithmetic.html > > inc/dec sound looser: > http://www.cs.purdue.edu/homes/hosking/m3/reference/incdec.html > > > I still think mixed operations are reasonable and the result types not so surprising. > a := b; > > vs. a := b + c; > > The first is clear even if and b have different types, but the second is not, if b and c have different types? > They seem pretty equally clear/unclear to me.. > > > - Jay > > > From: hosking at cs.purdue.edu > Date: Sat, 9 Jan 2010 23:22:44 -0500 > To: rodney_bates at lcwb.coop > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] index array by longint? > > That's very nice! I like it. I think we can use it.... > > Right now I am tracking bugs in range checking. Some were introduced by my LONGINT changes (sigh!) but others appear to have been around a while before that. > > For example: > > VAR s: CARDINAL := LAST(INTEGER); > BEGIN INC(s) END; > > did not result in a run-time error. I think I have fixed that now (commit to come). > > But, even worse: > > VAR s: CARDINAL := LAST(INTEGER); > BEGIN WITH x = s DO x := VAL(ORD(x) + 1, CARDINAL) END END; > > also does not give a run-time error. > > The result is that you can store FIRST(INTEGER) in a CARDINAL. Yikes! > > On 9 Jan 2010, at 21:54, Rodney M. Bates wrote: > > When writing my original proposal, I agonized at length over whether > to allow (subranges of) LONGINT to be the index type of an array type. In the > end, I decided that gave a poor ratio of practical benefit to language > and implementation complexity. > > However, note, from 2.6.3, "Designators, > > "a[i] > denotes the (i + 1 - FIRST(a))-th element of the array a. The expression a[i] is a > designator if a is, and is writable if a is. The expression i must be assignable > --------------------------------------------------------------------------^ > to the index type of a. The type of a[i] is the element type of a." > > So, by existing rules about assignability, when referring to an element of an > array, the subscript expression could have base type LONGINT, and would just > be "assigned" in the usual way to the index type, a subrange of INTEGER. > This is one of the dozen or so places assignability is used in the language. > > > > Jay K wrote: > Index array by longint? > With runtime check that it is <= LAST(INTEGER)? > Or really, with runtime bounds check against the array size. > Seems reasonable? > Aids the rd/wr change. > A little bit of pain to implement..unless INTEGER and LONGINT have a common base... > - Jay > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 08:58:56 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 07:58:56 +0000 Subject: [M3devel] index array by longint? In-Reply-To: <3D1F9FE5-412E-4F2F-9C6F-89DDA439D70F@cs.purdue.edu> References: , , <4B49417B.7060806@lcwb.coop>, , <4F4DE877-9495-4E2D-910C-F55473E92F06@cs.purdue.edu>, , , <2B01D3D0-70D5-4DDD-8778-965325B18588@cs.purdue.edu>, , <3D1F9FE5-412E-4F2F-9C6F-89DDA439D70F@cs.purdue.edu> Message-ID: It is easy to frame in terms of assignability? a + b is legal if a is assignable to b, or b is assignable to a If you don't allow INTEGER := LONGINT, then you can say, like: a + b is legal if a is assignable to b or b is assignable a (or both); if a and b are of different type, and only one is assignable to the other, then the result type is that of the assignable-to type. If INTEGER := LONGINT, then I'm not sure how to formally define the result. Something informal: a + b is legal if a or b is assignable to the other the result type is the "larger" or "wider" type -- whatever that means; However, I think there is an easy enough to define set of rules. It varies for each operator though. Basically, first, the notion of "larger" or "wider" isn't all that unscientific. It needs a little honing though; a + b is legal if a is assignable to b or b is assignable to a (or both). If a and b are of the same type, that is the result type. If a and b are of different types, but one of their types can represent without loss all the values of the other type, then that is the result type. If a and b are of different types, and neither type can represent all of the values of the other type, then the result type is INTEGER if it can represent all the members of the types of a and b, else LONGINT. The result type is stated in terms of the input types. Not in terms of the output range. This is a general fact of life with addition anyway. The result of adding two integers is an integer, even though integer cannot hold the output range. I have a strong suspicion that we would be more satisified with our rules if overflow checking was present. Heck, maybe we'd have something wierd where INTEGER + INTEGER actually yielded LONGINT, but then LONGINT is assignable to INTEGER? The overflow check would actually be at the assignment/narrowing? Heck, it's not like double precision arithmetic is even so expensive? What do you mean by, reworded, "the operators aren't typed" - Jay From: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 02:37:45 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] index array by longint? Try to frame this in terms of assignability... If the operators themselves were typed then there would be no problem. But when they aren't we get into a real mess trying to remember what the promotion rules are. On 10 Jan 2010, at 01:11, Jay K wrote: I don't think there is madness here. I believe the half range of CARDINAL helps avoid it. A confusing point in C is comparison that includes conversion is magnitude or sign preserving -- comparing int and unsigned. Back to Modula-3: a := b; c := a + d; vs. c := b + d; are different? Isn't that strange? Compare with a : = b; c := d[a]; and c := d[b]; we have decided they are the same, among others. There's something about "kinda sorta transitive" here. Or, like, "why should I have to move values through temporaries in some cases but not others?" - Jay Subject: Re: [M3devel] index array by longint? From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 23:46:39 -0500 CC: rodney_bates at lcwb.coop; m3devel at elegosoft.com To: jay.krell at cornell.edu I have a feeling that the mixed arithmetic option is losing favor. It is a slippery slope to C madness. On 9 Jan 2010, at 23:42, Jay K wrote: There are more cases: =, #, <, >, IN, etc. have this same "you can mix if they are assignable" rule. http://www.cs.purdue.edu/homes/hosking/m3/reference/relations.html infix =, # (x, y: Any): BOOLEAN The operator = returns TRUE if x and y are equal. The operator # returns TRUE if x and y are not equal. It is a static error if the type of x is not assignable to the type of y or vice versa. ... Other places demand equal types: http://www.cs.purdue.edu/homes/hosking/m3/reference/arithmetic.html inc/dec sound looser: http://www.cs.purdue.edu/homes/hosking/m3/reference/incdec.html I still think mixed operations are reasonable and the result types not so surprising. a := b; vs. a := b + c; The first is clear even if and b have different types, but the second is not, if b and c have different types? They seem pretty equally clear/unclear to me.. - Jay From: hosking at cs.purdue.edu Date: Sat, 9 Jan 2010 23:22:44 -0500 To: rodney_bates at lcwb.coop CC: m3devel at elegosoft.com Subject: Re: [M3devel] index array by longint? That's very nice! I like it. I think we can use it.... Right now I am tracking bugs in range checking. Some were introduced by my LONGINT changes (sigh!) but others appear to have been around a while before that. For example: VAR s: CARDINAL := LAST(INTEGER); BEGIN INC(s) END; did not result in a run-time error. I think I have fixed that now (commit to come). But, even worse: VAR s: CARDINAL := LAST(INTEGER); BEGIN WITH x = s DO x := VAL(ORD(x) + 1, CARDINAL) END END; also does not give a run-time error. The result is that you can store FIRST(INTEGER) in a CARDINAL. Yikes! On 9 Jan 2010, at 21:54, Rodney M. Bates wrote: When writing my original proposal, I agonized at length over whether to allow (subranges of) LONGINT to be the index type of an array type. In the end, I decided that gave a poor ratio of practical benefit to language and implementation complexity. However, note, from 2.6.3, "Designators, "a[i] denotes the (i + 1 - FIRST(a))-th element of the array a. The expression a[i] is a designator if a is, and is writable if a is. The expression i must be assignable --------------------------------------------------------------------------^ to the index type of a. The type of a[i] is the element type of a." So, by existing rules about assignability, when referring to an element of an array, the subscript expression could have base type LONGINT, and would just be "assigned" in the usual way to the index type, a subrange of INTEGER. This is one of the dozen or so places assignability is used in the language. Jay K wrote: Index array by longint? With runtime check that it is <= LAST(INTEGER)? Or really, with runtime bounds check against the array size. Seems reasonable? Aids the rd/wr change. A little bit of pain to implement..unless INTEGER and LONGINT have a common base... - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 09:55:31 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 08:55:31 +0000 Subject: [M3devel] another longint variant In-Reply-To: <20100110002552.683AA1A2078@async.async.caltech.edu> References: ,,, , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, ,,, , , , , , , <0DA1F27C-363E-43C8-AC09-E5FD1BDED6BC@cs.purdue.edu>, , <20100110002552.683AA1A2078@async.async.caltech.edu> Message-ID: > If there are "promotion rules" it's just not that obvious. I'm reminded of one > time when I was missing a prototype in a C program.............. ok that story > could go on and on. You were using a bad compiler or at least bad switches: C:\>type t.c void F1() { F2(); } C:\>cl -c -W4 -WX t.c Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. t.c t.c(5) : error C2220: warning treated as error - no 'object' file generated t.c(5) : warning C4013: 'F2' undefined; assuming extern returning int and C++ always errors. - Jay > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] another longint variant > Date: Sat, 9 Jan 2010 16:25:52 -0800 > From: mika at async.async.caltech.edu > > Jay K writes: > >--_953e6126-a89e-4966-8f22-5ccff92e7117_ > >Content-Type: text/plain; charset="iso-8859-1" > >Content-Transfer-Encoding: quoted-printable > > > > > > > I believe Rodney said something like "mixed operations follow from assig= > >nability"=3B > > > and from a language point of view=2C that may be true=2C just not from t= > >he point of view=3B > > > >I meant to say=2C not from the language implementation point of view. > > > >Again=2C if I can assign and then add=2C might as well just allow add? > >Ditto assign and index=2C assign and multiply=2C etc. > > > > The problem is that it's sometimes ambiguous what the result type is. > > If you want to get into this kind of mess, why don't you just program in C... > > I think this area is probably one of the reasons some people *like* Modula-3. > We don't want to have to guess what an expression means... it should be obvious. > If there are "promotion rules" it's just not that obvious. I'm reminded of one > time when I was missing a prototype in a C program.............. ok that story > could go on and on. > > Mika > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 10:10:52 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 09:10:52 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , Message-ID: Just a note that the version with ORD and VAL sprinkled everywhere is compatible with every proposal, *except* removing LONGINT altogether. It is ugly and tedious, but it does seem to work. Can we go with it?? Maybe "clean it up" afterward, if the compiler allows more? You basically just search for "LONGINT" or "VAL" across the tree... - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Subject: RE: [M3devel] what to do about file sizes being 32bits? Date: Thu, 7 Jan 2010 11:22:37 +0000 I'm working on this.. Attached is what I have so far. Posix needs work. Most code continues to not work for files >4GB on 32bit, but it is a start. It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. I'm not sure if the ToProc/FromProc stuff should use INTEGER/CARDINAL or LONGINT. This gets as far as: == package C:\dev2\cm3.2\m3-obliq\obliqrt == +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 -DCM3_VERSION_TEXT=d5.8.2 - DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ --- building in NT386 --- ignoring ..\src\m3overrides \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB m3cfe: (Error) failed to find source or AST for interface 'WordRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Word.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis suppressed due to import errors m3cfe: (Error) failed to find source or AST for interface 'LongRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Long.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic analysis suppresse d due to import errors "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic analysis suppr Which is probably some other problem? - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 09:47:07 +0000 Subject: Re: [M3devel] what to do about file sizes being 32bits? I think I can fix everything in the cm3 tree if size is changed to LONGINT. Including Index(), Length(), Seek(). It involves *many* uses of VAL and ORD, and indeed, it would help if: INC(longint, integer) was legal, which seems perfectly ok. longint := integer ditto Most of the toplevel users will end up throwing in ORD, as they require files to fit in memory/addressspace. There is still the matter of this will break too much code out there. - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 06:59:31 +0000 Subject: [M3devel] what to do about file sizes being 32bits? File.i3: Status = RECORD type: Type; modificationTime: Time.T; size: CARDINAL (* oops... *) END; What to do? [0.. higher than 7FFFFFFF] doesn't "just work". higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, which presumably has some relationship to turning it into a LONGINT, which causes users to fail to compile LONGINT doesn't "just work" causes users to fail to compile stale imports -> compiling ProcessPosixCommon.i3 stale imports -> compiling ProcessPosixCommon.m3 stale imports -> compiling ProcessPosix.m3 stale imports -> compiling FileRd.i3 missing version stamps -> compiling FileRd.m3 "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN "../src/rw/FileRd.m3", line 140: types are not assignable 2 errors encountered stale imports -> compiling FileWr.i3 missing version stamps -> compiling FileWr.m3 "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX 2 errors encountered st Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, hope the damage isn't too great outside the cm3 tree? Change it to LONGREAL so that it works immediately on NT386. Same issues as above, breaks existing users. Maybe relax the language some, so that e.g. a:INTEGER; b:LONGINT; b := a; just works, see if it helps make more code compile with the change? a := b is problematic of course, but what is wrong with b := a? - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 10:52:32 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 09:52:32 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , , Message-ID: Well, I have to take that back. I'm reading Rodney's proposal. https://mail.elegosoft.com/pipermail/m3devel/attachments/20100108/52ebf7d7/attachment.txt Notable so far: He allowed mixed operations. Though mixed MOD he makes LONGINT, which is natural to think and maybe is what we should do, though INTEGER suffices, at least for positive numbers. He defines ORD as possibly returning LONGINT. Which breaks my assertion below. But he doesn't allow indexing an array by LONGINT. Nor sets of LONGINT. I think this is just a tad limiting. You know, I might have a set that contains just a small range of longint. That isn't hard to implement? - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Sun, 10 Jan 2010 09:10:52 +0000 Subject: Re: [M3devel] what to do about file sizes being 32bits? Just a note that the version with ORD and VAL sprinkled everywhere is compatible with every proposal, *except* removing LONGINT altogether. It is ugly and tedious, but it does seem to work. Can we go with it?? Maybe "clean it up" afterward, if the compiler allows more? You basically just search for "LONGINT" or "VAL" across the tree... - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Subject: RE: [M3devel] what to do about file sizes being 32bits? Date: Thu, 7 Jan 2010 11:22:37 +0000 I'm working on this.. Attached is what I have so far. Posix needs work. Most code continues to not work for files >4GB on 32bit, but it is a start. It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. I'm not sure if the ToProc/FromProc stuff should use INTEGER/CARDINAL or LONGINT. This gets as far as: == package C:\dev2\cm3.2\m3-obliq\obliqrt == +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 -DCM3_VERSION_TEXT=d5.8.2 - DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ --- building in NT386 --- ignoring ..\src\m3overrides \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB m3cfe: (Error) failed to find source or AST for interface 'WordRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Word.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis suppressed due to import errors m3cfe: (Error) failed to find source or AST for interface 'LongRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Long.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic analysis suppresse d due to import errors "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic analysis suppr Which is probably some other problem? - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 09:47:07 +0000 Subject: Re: [M3devel] what to do about file sizes being 32bits? I think I can fix everything in the cm3 tree if size is changed to LONGINT. Including Index(), Length(), Seek(). It involves *many* uses of VAL and ORD, and indeed, it would help if: INC(longint, integer) was legal, which seems perfectly ok. longint := integer ditto Most of the toplevel users will end up throwing in ORD, as they require files to fit in memory/addressspace. There is still the matter of this will break too much code out there. - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 06:59:31 +0000 Subject: [M3devel] what to do about file sizes being 32bits? File.i3: Status = RECORD type: Type; modificationTime: Time.T; size: CARDINAL (* oops... *) END; What to do? [0.. higher than 7FFFFFFF] doesn't "just work". higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, which presumably has some relationship to turning it into a LONGINT, which causes users to fail to compile LONGINT doesn't "just work" causes users to fail to compile stale imports -> compiling ProcessPosixCommon.i3 stale imports -> compiling ProcessPosixCommon.m3 stale imports -> compiling ProcessPosix.m3 stale imports -> compiling FileRd.i3 missing version stamps -> compiling FileRd.m3 "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN "../src/rw/FileRd.m3", line 140: types are not assignable 2 errors encountered stale imports -> compiling FileWr.i3 missing version stamps -> compiling FileWr.m3 "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX 2 errors encountered st Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, hope the damage isn't too great outside the cm3 tree? Change it to LONGREAL so that it works immediately on NT386. Same issues as above, breaks existing users. Maybe relax the language some, so that e.g. a:INTEGER; b:LONGINT; b := a; just works, see if it helps make more code compile with the change? a := b is problematic of course, but what is wrong with b := a? - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 11:26:28 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 10:26:28 +0000 Subject: [M3devel] m3front broken Message-ID: Tony, with the recent changes: 1) *** *** runtime error: *** An array subscript was out of range. *** file "..\src\misc\Scanner.m3", line 351 *** Stack trace: FP PC Procedure --------- --------- ------------------------------- 0x12f774 0x49c8e2 NoteReserved + 0x44 in ..\src\misc\Scanner.m3 0x12f7ac 0x4cb247 Define + 0xf9 in ..\src\values\Procedure.m3 0x12f7d4 0x517b7b Initialize + 0xd5 in ..\src\builtinOps\Cas.m3 0x12f7e8 0x4b0320 Initialize + 0x30 in ..\src\builtinOps\BuiltinOps.m3 0x12f804 0x499341 Initialize + 0x9a in ..\src\misc\M3Front.m3 0x12f834 0x498f81 ParseImports + 0x151 in ..\src\misc\M3Front.m3 0x12f860 0x40a6eb Pass0_CheckImports + 0xa4 in ..\src\Builder.m3 0x12f8ac 0x409e87 RunM3 + 0x215 in ..\src\Builder.m3 0x12f8e8 0x40862c PushOneM3 + 0x10a in ..\src\Builder.m3 0x12f918 0x4084f9 CompileM3 + 0x21d in ..\src\Builder.m3 ......... ......... ... more frames ... 2) If I fix that by removing cas/casp more completely: C:\dev2\cm3.2\scripts\python>\bin\x86\cdb \cm3\bin\cm3 (254c.2440): Access violation - code c0000005 (first chance) cm3!RTType__HashBrand+0x41: 0064630a 8a5600 mov dl,byte ptr [esi] ds:0023:00ebb000=?? 0:000> r esi esi=00ebb000 0:000> db @esi - 4 00ebaffc 00 00 00 00 ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ....???????????? 0:000> .lines Line number information will be loaded 0:000> k ChildEBP RetAddr 0012fe4c 00644c90 cm3!RTType__HashBrand+0x41 [..\src\runtime\common\RTType.m3 @ 815] 0012fe70 00644db2 cm3!RTType__NoteBrand+0x1b [..\src\runtime\common\RTType.m3 @ 150] 0012fe94 00634928 cm3!RTTypeSRC__AddTypecell+0xa3 [..\src\runtime\common\RTType. m3 @ 170] 0012fec4 006346d1 cm3!RTLinker__DeclareModuleTypes+0x101 [..\src\runtime\common\ RTLinker.m3 @ 287] 0012fef8 00634227 cm3!RTLinker__FixTypes+0x8a [..\src\runtime\common\RTLinker.m3 @ 234] 0012ff0c 006342e5 cm3!RTLinker__AddUnitI+0xe2 [..\src\runtime\common\RTLinker.m3 @ 113] 0012ff30 00633f72 cm3!RTLinker__AddUnit+0xa1 [..\src\runtime\common\RTLinker.m3 @ 122] 0012ff54 00401029 cm3!RTLinker__InitRuntime+0x92 [..\src\runtime\common\RTLinker .m3 @ 42] 0012ff7c 00675fda cm3!main+0x29 [_m3main.mc @ 3] 0012ffc0 7c817077 cm3!__tmainCRTStartup+0x10f [f:\dd\vctools\crt_bld\self_x86\cr t\src\crtexe.c @ 582] 0012fff0 00000000 kernel32!BaseProcessStart+0x23 0:000> looks like maybe an off by one problem? Since the pointer is near valid memory? Any ideas? I'll poke around. Going back to the release branch versions fixes this. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 11:38:52 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 10:38:52 +0000 Subject: [M3devel] m3front broken In-Reply-To: References: Message-ID: nevermind, I see the problem, fix shortly - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu; m3devel at elegosoft.com Date: Sun, 10 Jan 2010 10:26:28 +0000 Subject: [M3devel] m3front broken Tony, with the recent changes: 1) *** *** runtime error: *** An array subscript was out of range. *** file "..\src\misc\Scanner.m3", line 351 *** Stack trace: FP PC Procedure --------- --------- ------------------------------- 0x12f774 0x49c8e2 NoteReserved + 0x44 in ..\src\misc\Scanner.m3 0x12f7ac 0x4cb247 Define + 0xf9 in ..\src\values\Procedure.m3 0x12f7d4 0x517b7b Initialize + 0xd5 in ..\src\builtinOps\Cas.m3 0x12f7e8 0x4b0320 Initialize + 0x30 in ..\src\builtinOps\BuiltinOps.m3 0x12f804 0x499341 Initialize + 0x9a in ..\src\misc\M3Front.m3 0x12f834 0x498f81 ParseImports + 0x151 in ..\src\misc\M3Front.m3 0x12f860 0x40a6eb Pass0_CheckImports + 0xa4 in ..\src\Builder.m3 0x12f8ac 0x409e87 RunM3 + 0x215 in ..\src\Builder.m3 0x12f8e8 0x40862c PushOneM3 + 0x10a in ..\src\Builder.m3 0x12f918 0x4084f9 CompileM3 + 0x21d in ..\src\Builder.m3 ......... ......... ... more frames ... 2) If I fix that by removing cas/casp more completely: C:\dev2\cm3.2\scripts\python>\bin\x86\cdb \cm3\bin\cm3 (254c.2440): Access violation - code c0000005 (first chance) cm3!RTType__HashBrand+0x41: 0064630a 8a5600 mov dl,byte ptr [esi] ds:0023:00ebb000=?? 0:000> r esi esi=00ebb000 0:000> db @esi - 4 00ebaffc 00 00 00 00 ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ....???????????? 0:000> .lines Line number information will be loaded 0:000> k ChildEBP RetAddr 0012fe4c 00644c90 cm3!RTType__HashBrand+0x41 [..\src\runtime\common\RTType.m3 @ 815] 0012fe70 00644db2 cm3!RTType__NoteBrand+0x1b [..\src\runtime\common\RTType.m3 @ 150] 0012fe94 00634928 cm3!RTTypeSRC__AddTypecell+0xa3 [..\src\runtime\common\RTType. m3 @ 170] 0012fec4 006346d1 cm3!RTLinker__DeclareModuleTypes+0x101 [..\src\runtime\common\ RTLinker.m3 @ 287] 0012fef8 00634227 cm3!RTLinker__FixTypes+0x8a [..\src\runtime\common\RTLinker.m3 @ 234] 0012ff0c 006342e5 cm3!RTLinker__AddUnitI+0xe2 [..\src\runtime\common\RTLinker.m3 @ 113] 0012ff30 00633f72 cm3!RTLinker__AddUnit+0xa1 [..\src\runtime\common\RTLinker.m3 @ 122] 0012ff54 00401029 cm3!RTLinker__InitRuntime+0x92 [..\src\runtime\common\RTLinker .m3 @ 42] 0012ff7c 00675fda cm3!main+0x29 [_m3main.mc @ 3] 0012ffc0 7c817077 cm3!__tmainCRTStartup+0x10f [f:\dd\vctools\crt_bld\self_x86\cr t\src\crtexe.c @ 582] 0012fff0 00000000 kernel32!BaseProcessStart+0x23 0:000> looks like maybe an off by one problem? Since the pointer is near valid memory? Any ideas? I'll poke around. Going back to the release branch versions fixes this. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 12:29:21 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 11:29:21 +0000 Subject: [M3devel] yet another longint rendition -- just mutual assignability, result is very tedious Message-ID: These diffs show what you can do if you merely allow assignability between integer and longint, both ways. The compiler diff is included. This is just what it takes to get libm3 to compile, having changed a few integer to longint. It's pretty awful in my opinion. No changed made outside m3front and libm3, and there would surely be "many" needed, like the first set of diffs I sent. (I think those were written with no compiler change at all.) I believe people wanted to see what this looks like. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 1.txt URL: From hosking at cs.purdue.edu Sun Jan 10 15:30:00 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sun, 10 Jan 2010 09:30:00 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , Message-ID: I still want to see the patch... Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On 10 Jan 2010, at 04:10, Jay K wrote: > Just a note that the version with ORD and VAL sprinkled everywhere > is compatible with every proposal, *except* removing LONGINT altogether. > It is ugly and tedious, but it does seem to work. > > Can we go with it?? > > Maybe "clean it up" afterward, if the compiler allows more? > You basically just search for "LONGINT" or "VAL" across the tree... > > > - Jay > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Subject: RE: [M3devel] what to do about file sizes being 32bits? > Date: Thu, 7 Jan 2010 11:22:37 +0000 > > I'm working on this.. > Attached is what I have so far. > Posix needs work. > Most code continues to not work for files >4GB on 32bit, but it is a start. > It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. > Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. > I'm not sure if the ToProc/FromProc stuff should use INTEGER/CARDINAL or LONGINT. > > This gets as far as: > > == package C:\dev2\cm3.2\m3-obliq\obliqrt == > > +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 -DCM3_VERSION_TEXT=d5.8.2 - > DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ > --- building in NT386 --- > > ignoring ..\src\m3overrides > > \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB > m3cfe: (Error) failed to find source or AST for interface 'WordRep' > "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Word.i3]": semanti > c analysis suppressed due to import errors > "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis suppressed due > to import errors > m3cfe: (Error) failed to find source or AST for interface 'LongRep' > "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Long.i3]": semanti > c analysis suppressed due to import errors > "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic analysis suppresse > d due to import errors > "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic analysis suppr > > > Which is probably some other problem? > > > - Jay > > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 09:47:07 +0000 > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > I think I can fix everything in the cm3 tree if size is changed to LONGINT. > Including Index(), Length(), Seek(). > It involves *many* uses of VAL and ORD, and indeed, it would help if: > > > INC(longint, integer) was legal, which seems perfectly ok. > longint := integer ditto > > > Most of the toplevel users will end up throwing in ORD, as they > require files to fit in memory/addressspace. > > > There is still the matter of this will break too much code out there. > > > - Jay > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 06:59:31 +0000 > Subject: [M3devel] what to do about file sizes being 32bits? > > File.i3: > > > Status = RECORD > type: Type; > modificationTime: Time.T; > size: CARDINAL (* oops... *) > END; > > > What to do? > [0.. higher than 7FFFFFFF] doesn't "just work". > higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, > which presumably has some relationship to turning it into a LONGINT, which > causes users to fail to compile > > > LONGINT doesn't "just work" > causes users to fail to compile > > > stale imports -> compiling ProcessPosixCommon.i3 > stale imports -> compiling ProcessPosixCommon.m3 > stale imports -> compiling ProcessPosix.m3 > stale imports -> compiling FileRd.i3 > missing version stamps -> compiling FileRd.m3 > "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN > "../src/rw/FileRd.m3", line 140: types are not assignable > 2 errors encountered > stale imports -> compiling FileWr.i3 > missing version stamps -> compiling FileWr.m3 > "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN > "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX > 2 errors encountered > st > > > Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, > hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGREAL so that it works immediately on NT386. > Same issues as above, breaks existing users. > > > Maybe relax the language some, so that e.g. > a:INTEGER; > b:LONGINT; > > b := a; > > just works, see if it helps make more code compile with the change? > > a := b is problematic of course, but what is wrong with b := a? > > - Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rcolebur at SCIRES.COM Sun Jan 10 21:00:58 2010 From: rcolebur at SCIRES.COM (Randy Coleburn) Date: Sun, 10 Jan 2010 15:00:58 -0500 Subject: [M3devel] the LONGINT proposal In-Reply-To: <20100110051218.2F3C42474001@birch.elegosoft.com> References: <20100110051218.2F3C42474001@birch.elegosoft.com> Message-ID: I've been trying to follow along on this topic. Here are my thoughts: 1. LONGINT should be a distinct type different from INTEGER. 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. 3. Overflow should be a checked run-time error, not silently wrapped around. 4. WRT assignability, I think explicit conversions should be used. These statements may make me unpopular with some who don't like to type much, but I've always hated the tradeoff of understandability for brevity in expression. The important thing is not how fast we can type up a program, it is rather how hard is it to make a mistake. I think the spirit of Modula-3 is that the language makes you a better programmer by forcing you to make your intentions explicit rather than relying on the compiler to infer your intentions. We need correct and maintainable software, especially at the systems level. Whatever is decided about LONGINT, we need to keep to the original design tenants of the language. And yes, I do think we need a LONGINT type, not just to deal with large file sizes. But even for long-lived readers/writers, whatever type you choose for the index will eventually be insufficient, so you have to code for the possibility that the range of the long lived reader/writer exceeds the range of your index type. That is just good programming. I think sometimes that the new generation of programmers has been warped by what I call the "Microsoft Mentality" where you must expect that you need to reboot/restart every so often to maintain proper performance. Programs should be written to run forever or until their job is completed or they are commanded to stop. As "we" begin to converge on the design changes, I like having something concrete to look at, ala Rodney's proposal. Can we take that and keep tweaking it in these emails until we reach a final version acceptable to all? To me this keeps the discussion focused rather than the many different emails. Thus, what I am trying to say is put forth a numbered proposal and each subsequent email must show adjustment to that proposal rather than just a bunch of emails discussing various aspects. Perhaps we should vote on each proposed change, then decide to call a final vote on the whole thing. Who should be involved in such votes? Right now the main persons on the thread are Tony, Jay, Rodney, Mika, Hendrik, Olaf, John, and me. My two cents. Regards, Randy Coleburn From hosking at cs.purdue.edu Sun Jan 10 21:23:28 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sun, 10 Jan 2010 15:23:28 -0500 Subject: [M3devel] Integer literals Message-ID: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu> One thing I've really struggled with over the introduction of LONGINT is the need for distinct literal forms. This strikes me as odd, since literals are really just ways of writing values, rather than stating anything about how they should be represented. (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, but they really do have incompatible value representations). It strikes me that with checked assignability for INTEGER/LONGINT we could also potentially treat integer literals as essentially "untyped" (neither INTEGER nor LONGINT). (I still strongly resist going the route of having mixed type operands for arithmetic...) Here's how things would work with subrange types. A subrange written as currently [lo .. hi] would by default be assumed to have base type INTEGER. The constants lo/hi must both be in range for INTEGER. A subrange with base type LONGINT would be written explicitly: [lo .. hi] OF LONGINT The constants lo/hi must both be in range for LONGINT. We could also support the form: [lo .. hi] OF INTEGER just for consistency though the "OF INTEGER" qualification would be unnecessarily verbose. Here we are allowing the programmer to state explicitly what the base type of the subrange should be. Literals would be be range-checked when used as arithmetic operands or in assignment, with compile-time checks that they are in range ("compatible") with the types of the other operands or the destination of the assignment. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 21:34:59 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 20:34:59 +0000 Subject: [M3devel] the LONGINT proposal In-Reply-To: References: <20100110051218.2F3C42474001@birch.elegosoft.com>, Message-ID: > 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. > > 4. WRT assignability, I think explicit conversions should be used. > Have you seen the resulting diffs? Would we just say, that the initial rd/wr interface was so wrong, that there is a lot of "incorrect" code, so the ugly diff is the result? That newer code wouldn't be so initially wrong, so would remain not so ugly? Maybe. VAR a:LONGINT; b:INTEGER; INC(a, b); doesn't that make perfect sense to even the most casual reader? Many current proposals don't allow it. Though Randy's does allow it. Indexing by LONGINT is also trivial. Just do the usual range check and go. Indexing by INTEGER also has a range check. One difference would be that a subrange of LONGINTs that are all greater than LAST(INTEGER) could be a stack error, just as some indexing by INTEGER subranges can also be a static error (e.g. if the array element size times the all the elements of the subrange or enum are larger than the address space). > We need correct and maintainable software, especially at the systems level Nearly all systems level software is written in a language or languages that manage to zero extend or sign extend integers to wider integers. The Modula-3 compiler/runtime/garbage collector is the biggest exception I can think of, but so far it can't really handle large files. - Jay > From: rcolebur at SCIRES.COM > To: m3devel at elegosoft.com > Date: Sun, 10 Jan 2010 15:00:58 -0500 > Subject: [M3devel] the LONGINT proposal > > I've been trying to follow along on this topic. > > Here are my thoughts: > > 1. LONGINT should be a distinct type different from INTEGER. > > 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. > > 3. Overflow should be a checked run-time error, not silently wrapped around. > > 4. WRT assignability, I think explicit conversions should be used. > > These statements may make me unpopular with some who don't like to type much, but I've always hated the tradeoff of understandability for brevity in expression. > > The important thing is not how fast we can type up a program, it is rather how hard is it to make a mistake. I think the spirit of Modula-3 is that the language makes you a better programmer by forcing you to make your intentions explicit rather than relying on the compiler to infer your intentions. We need correct and maintainable software, especially at the systems level. Whatever is decided about LONGINT, we need to keep to the original design tenants of the language. > > And yes, I do think we need a LONGINT type, not just to deal with large file sizes. > > But even for long-lived readers/writers, whatever type you choose for the index will eventually be insufficient, so you have to code for the possibility that the range of the long lived reader/writer exceeds the range of your index type. That is just good programming. > > I think sometimes that the new generation of programmers has been warped by what I call the "Microsoft Mentality" where you must expect that you need to reboot/restart every so often to maintain proper performance. Programs should be written to run forever or until their job is completed or they are commanded to stop. > > As "we" begin to converge on the design changes, I like having something concrete to look at, ala Rodney's proposal. Can we take that and keep tweaking it in these emails until we reach a final version acceptable to all? To me this keeps the discussion focused rather than the many different emails. Thus, what I am trying to say is put forth a numbered proposal and each subsequent email must show adjustment to that proposal rather than just a bunch of emails discussing various aspects. Perhaps we should vote on each proposed change, then decide to call a final vote on the whole thing. Who should be involved in such votes? Right now the main persons on the thread are Tony, Jay, Rodney, Mika, Hendrik, Olaf, John, and me. > > My two cents. > > Regards, > Randy Coleburn -------------- next part -------------- An HTML attachment was scrubbed... URL: From hendrik at topoi.pooq.com Sun Jan 10 21:38:32 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Sun, 10 Jan 2010 15:38:32 -0500 Subject: [M3devel] Integer literals In-Reply-To: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu> References: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu> Message-ID: <20100110203832.GA16635@topoi.pooq.com> On Sun, Jan 10, 2010 at 03:23:28PM -0500, Tony Hosking wrote: > One thing I've really struggled with over the introduction of LONGINT is the need for distinct literal forms. This strikes me as odd, since literals are really just ways of writing values, rather than stating anything about how they should be represented. > (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, but they really do have incompatible value representations). > > It strikes me that with checked assignability for INTEGER/LONGINT we could also potentially treat integer literals as essentially "untyped" (neither INTEGER nor LONGINT). (I still strongly resist going the route of having mixed type operands for arithmetic...) > > Here's how things would work with subrange types. > > A subrange written as currently > > [lo .. hi] > > would by default be assumed to have base type INTEGER. The constants lo/hi must both be in range for INTEGER. > > A subrange with base type LONGINT would be written explicitly: > > [lo .. hi] OF LONGINT > > The constants lo/hi must both be in range for LONGINT. > > We could also support the form: > > [lo .. hi] OF INTEGER > > just for consistency though the "OF INTEGER" qualification would be unnecessarily verbose. > > Here we are allowing the programmer to state explicitly what the base type of the subrange should be. > > Literals would be be range-checked when used as arithmetic operands or > in assignment, with compile-time checks that they are in range > ("compatible") with the types of the other operands or the destination > of the assignment. And what would be the type of 2000000000 + 2000000000? Overflow because 2000000000 is an INTEGER? Whereas 3000000000 + 3000000000 would end up being LONGINT? The only solutions I see for this problem are: (a) Explicitly tag every literal to identify it as INTEGER or LONGINT. or (b) Let operations on integers automatically produce values of sufficiently large ranges to be able to contain the results. (b) seems to be incompatible with the use of the most efficient integer operations on a machinem=, which are of fixed bit-width. (a) is what's proposed for the LONGINT extension. It would be possible to combine (a) and (b), using (b) only for LONGINT, but you seem to be dead set against this. -- hendrik > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > From hosking at cs.purdue.edu Sun Jan 10 21:42:55 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sun, 10 Jan 2010 15:42:55 -0500 Subject: [M3devel] the LONGINT proposal In-Reply-To: References: <20100110051218.2F3C42474001@birch.elegosoft.com> Message-ID: <73D2F123-F308-4210-9655-1F80F9A5C370@cs.purdue.edu> Hi Randy, As someone who has actually written Modula-3 programs for a living your opinions are always highly valued. I agree with you in principle and aims, except for requiring overflow to be a checked run-time error. The language definition already has a mechanism for handling this in the require FloatMode interface. It is not something that the compiler should be involved in. I also just now raised a question about perhaps having integer literals adapt their type to the context in which they are used. I should point out that the current mainline implementation does exactly what you propose (except overflow checking). It captures the fundamental spirit of Rodney's proposal but does not permit mixed arithmetic or assignment. Can I ask what your issue is w.r.to checked assignability? I am still leaning in favor. It is not much different from assignment from an INTEGER to a subrange, which requires no explicit check, though of course there is a run-time range check. Having programmers explicitly write: x: INTEGER := ORD(longint, INTEGER); seems unnecessary when they could just write x: INTEGER := longint; This is similar in spirit to: x: [lo..hi] := integer; On 10 Jan 2010, at 15:00, Randy Coleburn wrote: > I've been trying to follow along on this topic. > > Here are my thoughts: > > 1. LONGINT should be a distinct type different from INTEGER. > > 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. > > 3. Overflow should be a checked run-time error, not silently wrapped around. > > 4. WRT assignability, I think explicit conversions should be used. > > These statements may make me unpopular with some who don't like to type much, but I've always hated the tradeoff of understandability for brevity in expression. > > The important thing is not how fast we can type up a program, it is rather how hard is it to make a mistake. I think the spirit of Modula-3 is that the language makes you a better programmer by forcing you to make your intentions explicit rather than relying on the compiler to infer your intentions. We need correct and maintainable software, especially at the systems level. Whatever is decided about LONGINT, we need to keep to the original design tenants of the language. > > And yes, I do think we need a LONGINT type, not just to deal with large file sizes. > > But even for long-lived readers/writers, whatever type you choose for the index will eventually be insufficient, so you have to code for the possibility that the range of the long lived reader/writer exceeds the range of your index type. That is just good programming. > > I think sometimes that the new generation of programmers has been warped by what I call the "Microsoft Mentality" where you must expect that you need to reboot/restart every so often to maintain proper performance. Programs should be written to run forever or until their job is completed or they are commanded to stop. > > As "we" begin to converge on the design changes, I like having something concrete to look at, ala Rodney's proposal. Can we take that and keep tweaking it in these emails until we reach a final version acceptable to all? To me this keeps the discussion focused rather than the many different emails. Thus, what I am trying to say is put forth a numbered proposal and each subsequent email must show adjustment to that proposal rather than just a bunch of emails discussing various aspects. Perhaps we should vote on each proposed change, then decide to call a final vote on the whole thing. Who should be involved in such votes? Right now the main persons on the thread are Tony, Jay, Rodney, Mika, Hendrik, Olaf, John, and me. > > My two cents. > > Regards, > Randy Coleburn -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 21:43:27 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 20:43:27 +0000 Subject: [M3devel] Integer literals In-Reply-To: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu> References: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu> Message-ID: Seems fine either way. Assignability gives us, which we were missing before, VAR a:LONGINT := 0; > (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, but they really > do have incompatible value representations). I keep seeing this and am surprised. Isn't it the case that REAL <= LONGREAL <= EXTENDED in terms of precision and range? LONGREAL can losslessly represent all the values that REAL can represent, and possibly more (yes); EXTENDED can losslessly representa ll the values that LONGREAL can represent, and possibly more (not); And then, if that is true, mixing should be allowed..widen any constituents in an expression to the widest type. I realize mixing floating point and integer is less natural, nothing about floating point is natural really, though on a 32bit platform LONGREAL can hold all INTEGERS.. - Jay From: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 15:23:28 -0500 To: m3devel at elegosoft.com Subject: [M3devel] Integer literals One thing I've really struggled with over the introduction of LONGINT is the need for distinct literal forms. This strikes me as odd, since literals are really just ways of writing values, rather than stating anything about how they should be represented. (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, but they really do have incompatible value representations). It strikes me that with checked assignability for INTEGER/LONGINT we could also potentially treat integer literals as essentially "untyped" (neither INTEGER nor LONGINT). (I still strongly resist going the route of having mixed type operands for arithmetic...) Here's how things would work with subrange types. A subrange written as currently [lo .. hi] would by default be assumed to have base type INTEGER. The constants lo/hi must both be in range for INTEGER. A subrange with base type LONGINT would be written explicitly: [lo .. hi] OF LONGINT The constants lo/hi must both be in range for LONGINT. We could also support the form: [lo .. hi] OF INTEGER just for consistency though the "OF INTEGER" qualification would be unnecessarily verbose. Here we are allowing the programmer to state explicitly what the base type of the subrange should be. Literals would be be range-checked when used as arithmetic operands or in assignment, with compile-time checks that they are in range ("compatible") with the types of the other operands or the destination of the assignment. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 21:45:23 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 20:45:23 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , , , Message-ID: I've sent various patches. I believe the first had no compiler changes and built the whole tree. The second had maximum compiler changes (except for FOR) and built the whole tree. The third had only assignability and built just libm3. To build the whole tree you'd pretty much add all of the first diff. A few lines could be saved but not much. Assignability doesn't buy very much. I can do that if you want: assignability and build the whole tree. But we do know just about what it looks like. - Jay From: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 09:30:00 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] what to do about file sizes being 32bits? I still want to see the patch... Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 On 10 Jan 2010, at 04:10, Jay K wrote: Just a note that the version with ORD and VAL sprinkled everywhere is compatible with every proposal, *except* removing LONGINT altogether. It is ugly and tedious, but it does seem to work. Can we go with it?? Maybe "clean it up" afterward, if the compiler allows more? You basically just search for "LONGINT" or "VAL" across the tree... - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Subject: RE: [M3devel] what to do about file sizes being 32bits? Date: Thu, 7 Jan 2010 11:22:37 +0000 I'm working on this.. Attached is what I have so far. Posix needs work. Most code continues to not work for files >4GB on 32bit, but it is a start. It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. I'm not sure if the ToProc/FromProc stuff should use INTEGER/CARDINAL or LONGINT. This gets as far as: == package C:\dev2\cm3.2\m3-obliq\obliqrt == +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 -DCM3_VERSION_TEXT=d5.8.2 - DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ --- building in NT386 --- ignoring ..\src\m3overrides \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB m3cfe: (Error) failed to find source or AST for interface 'WordRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Word.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis suppressed due to import errors m3cfe: (Error) failed to find source or AST for interface 'LongRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Long.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic analysis suppresse d due to import errors "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic analysis suppr Which is probably some other problem? - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 09:47:07 +0000 Subject: Re: [M3devel] what to do about file sizes being 32bits? I think I can fix everything in the cm3 tree if size is changed to LONGINT. Including Index(), Length(), Seek(). It involves *many* uses of VAL and ORD, and indeed, it would help if: INC(longint, integer) was legal, which seems perfectly ok. longint := integer ditto Most of the toplevel users will end up throwing in ORD, as they require files to fit in memory/addressspace. There is still the matter of this will break too much code out there. - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 06:59:31 +0000 Subject: [M3devel] what to do about file sizes being 32bits? File.i3: Status = RECORD type: Type; modificationTime: Time.T; size: CARDINAL (* oops... *) END; What to do? [0.. higher than 7FFFFFFF] doesn't "just work". higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, which presumably has some relationship to turning it into a LONGINT, which causes users to fail to compile LONGINT doesn't "just work" causes users to fail to compile stale imports -> compiling ProcessPosixCommon.i3 stale imports -> compiling ProcessPosixCommon.m3 stale imports -> compiling ProcessPosix.m3 stale imports -> compiling FileRd.i3 missing version stamps -> compiling FileRd.m3 "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN "../src/rw/FileRd.m3", line 140: types are not assignable 2 errors encountered stale imports -> compiling FileWr.i3 missing version stamps -> compiling FileWr.m3 "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX 2 errors encountered st Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, hope the damage isn't too great outside the cm3 tree? Change it to LONGREAL so that it works immediately on NT386. Same issues as above, breaks existing users. Maybe relax the language some, so that e.g. a:INTEGER; b:LONGINT; b := a; just works, see if it helps make more code compile with the change? a := b is problematic of course, but what is wrong with b := a? - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 21:48:21 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sun, 10 Jan 2010 15:48:21 -0500 Subject: [M3devel] Integer literals In-Reply-To: <20100110203832.GA16635@topoi.pooq.com> References: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu> <20100110203832.GA16635@topoi.pooq.com> Message-ID: <63BBCB94-EB03-45FE-B13A-4AC4F273E538@cs.purdue.edu> On 10 Jan 2010, at 15:38, hendrik at topoi.pooq.com wrote: > On Sun, Jan 10, 2010 at 03:23:28PM -0500, Tony Hosking wrote: >> One thing I've really struggled with over the introduction of LONGINT is the need for distinct literal forms. This strikes me as odd, since literals are really just ways of writing values, rather than stating anything about how they should be represented. >> (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, but they really do have incompatible value representations). >> >> It strikes me that with checked assignability for INTEGER/LONGINT we could also potentially treat integer literals as essentially "untyped" (neither INTEGER nor LONGINT). (I still strongly resist going the route of having mixed type operands for arithmetic...) >> >> Here's how things would work with subrange types. >> >> A subrange written as currently >> >> [lo .. hi] >> >> would by default be assumed to have base type INTEGER. The constants lo/hi must both be in range for INTEGER. >> >> A subrange with base type LONGINT would be written explicitly: >> >> [lo .. hi] OF LONGINT >> >> The constants lo/hi must both be in range for LONGINT. >> >> We could also support the form: >> >> [lo .. hi] OF INTEGER >> >> just for consistency though the "OF INTEGER" qualification would be unnecessarily verbose. >> >> Here we are allowing the programmer to state explicitly what the base type of the subrange should be. >> >> Literals would be be range-checked when used as arithmetic operands or >> in assignment, with compile-time checks that they are in range >> ("compatible") with the types of the other operands or the destination >> of the assignment. > > And what would be the type of 2000000000 + 2000000000? Overflow because > 2000000000 is an INTEGER? Constant expressions would retain their "value" nature so long as the expression can be computed at compile-time without overflow up to the precision of LONGINT. > Whereas 3000000000 + 3000000000 would end up being LONGINT? > > The only solutions I see for this problem are: > > (a) Explicitly tag every literal to identify it as INTEGER or LONGINT. This is the current implementation. 0 and 0L are the same value as INTEGER and LONGINT. > > or > > (b) Let operations on integers automatically produce values of > sufficiently large ranges to be able to contain the results. Problematic because it imposes expensive operations on natural integers. > (b) seems to be incompatible with the use of the most efficient integer > operations on a machinem=, which are of fixed bit-width. Right. > (a) is what's proposed for the LONGINT extension. Not just proposed. Implemented now for over a year. > It would be possible to combine (a) and (b), using (b) only for LONGINT, > but you seem to be dead set against this. Indeed, I am. > > -- hendrik > >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> From hosking at cs.purdue.edu Sun Jan 10 21:51:17 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sun, 10 Jan 2010 15:51:17 -0500 Subject: [M3devel] Integer literals In-Reply-To: References: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu> Message-ID: <95DC398D-37D2-4B11-98F7-ED87D1CC9895@cs.purdue.edu> No! You're missing my whole point about representation. With what you are proposing here for the float types you will end up with implicit conversion operations performed in the hardware. The whole idea with explicit conversions is that programmers don't end up coding something that they have not transparently written. That is a fundamental and highly-valued design principle with Modula-3. We are not trying to reinvent C here. On 10 Jan 2010, at 15:43, Jay K wrote: > Seems fine either way. > Assignability gives us, which we were missing before, VAR a:LONGINT := 0; > > > > (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, but they really > > do have incompatible value representations). > > > I keep seeing this and am surprised. > Isn't it the case that REAL <= LONGREAL <= EXTENDED > in terms of precision and range? > LONGREAL can losslessly represent all the values that REAL can represent, and possibly more (yes); > EXTENDED can losslessly representa ll the values that LONGREAL can represent, and possibly more (not); > > > And then, if that is true, mixing should be allowed..widen any constituents > in an expression to the widest type. > > > I realize mixing floating point and integer is less natural, nothing about > floating point is natural really, though on a 32bit platform > LONGREAL can hold all INTEGERS.. > > - Jay > > > From: hosking at cs.purdue.edu > Date: Sun, 10 Jan 2010 15:23:28 -0500 > To: m3devel at elegosoft.com > Subject: [M3devel] Integer literals > > One thing I've really struggled with over the introduction of LONGINT is the need for distinct literal forms. This strikes me as odd, since literals are really just ways of writing values, rather than stating anything about how they should be represented. > (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, but they really do have incompatible value representations). > > It strikes me that with checked assignability for INTEGER/LONGINT we could also potentially treat integer literals as essentially "untyped" (neither INTEGER nor LONGINT). (I still strongly resist going the route of having mixed type operands for arithmetic...) > > Here's how things would work with subrange types. > > A subrange written as currently > > [lo .. hi] > > would by default be assumed to have base type INTEGER. The constants lo/hi must both be in range for INTEGER. > > A subrange with base type LONGINT would be written explicitly: > > [lo .. hi] OF LONGINT > > The constants lo/hi must both be in range for LONGINT. > > We could also support the form: > > [lo .. hi] OF INTEGER > > just for consistency though the "OF INTEGER" qualification would be unnecessarily verbose. > > Here we are allowing the programmer to state explicitly what the base type of the subrange should be. > > Literals would be be range-checked when used as arithmetic operands or in assignment, with compile-time checks that they are in range ("compatible") with the types of the other operands or the destination of the assignment. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 21:52:16 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sun, 10 Jan 2010 15:52:16 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , , , Message-ID: Thanks. I needed that refresher just to remember what your design space had been. On 10 Jan 2010, at 15:45, Jay K wrote: > I've sent various patches. > I believe the first had no compiler changes and built the whole tree. > The second had maximum compiler changes (except for FOR) and built the whole tree. > The third had only assignability and built just libm3. > To build the whole tree you'd pretty much add all of the first diff. A few lines > could be saved but not much. Assignability doesn't buy very much. > I can do that if you want: assignability and build the whole tree. > But we do know just about what it looks like. > > - Jay > > > > From: hosking at cs.purdue.edu > Date: Sun, 10 Jan 2010 09:30:00 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > I still want to see the patch... > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 > > > > > On 10 Jan 2010, at 04:10, Jay K wrote: > > Just a note that the version with ORD and VAL sprinkled everywhere > is compatible with every proposal, *except* removing LONGINT altogether. > It is ugly and tedious, but it does seem to work. > > Can we go with it?? > > Maybe "clean it up" afterward, if the compiler allows more? > You basically just search for "LONGINT" or "VAL" across the tree... > > > - Jay > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Subject: RE: [M3devel] what to do about file sizes being 32bits? > Date: Thu, 7 Jan 2010 11:22:37 +0000 > > I'm working on this.. > Attached is what I have so far. > Posix needs work. > Most code continues to not work for files >4GB on 32bit, but it is a start. > It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. > Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. > I'm not sure if the ToProc/FromProc stuff should use INTEGER/CARDINAL or LONGINT. > > This gets as far as: > > == package C:\dev2\cm3.2\m3-obliq\obliqrt == > > +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 -DCM3_VERSION_TEXT=d5.8.2 - > DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ > --- building in NT386 --- > > ignoring ..\src\m3overrides > > \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB > m3cfe: (Error) failed to find source or AST for interface 'WordRep' > "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Word.i3]": semanti > c analysis suppressed due to import errors > "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis suppressed due > to import errors > m3cfe: (Error) failed to find source or AST for interface 'LongRep' > "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Long.i3]": semanti > c analysis suppressed due to import errors > "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic analysis suppresse > d due to import errors > "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic analysis suppr > > > Which is probably some other problem? > > > - Jay > > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 09:47:07 +0000 > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > I think I can fix everything in the cm3 tree if size is changed to LONGINT. > Including Index(), Length(), Seek(). > It involves *many* uses of VAL and ORD, and indeed, it would help if: > > > INC(longint, integer) was legal, which seems perfectly ok. > longint := integer ditto > > > Most of the toplevel users will end up throwing in ORD, as they > require files to fit in memory/addressspace. > > > There is still the matter of this will break too much code out there. > > > - Jay > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 06:59:31 +0000 > Subject: [M3devel] what to do about file sizes being 32bits? > > File.i3: > > > Status = RECORD > type: Type; > modificationTime: Time.T; > size: CARDINAL (* oops... *) > END; > > > What to do? > [0.. higher than 7FFFFFFF] doesn't "just work". > higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, > which presumably has some relationship to turning it into a LONGINT, which > causes users to fail to compile > > > LONGINT doesn't "just work" > causes users to fail to compile > > > stale imports -> compiling ProcessPosixCommon.i3 > stale imports -> compiling ProcessPosixCommon.m3 > stale imports -> compiling ProcessPosix.m3 > stale imports -> compiling FileRd.i3 > missing version stamps -> compiling FileRd.m3 > "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN > "../src/rw/FileRd.m3", line 140: types are not assignable > 2 errors encountered > stale imports -> compiling FileWr.i3 > missing version stamps -> compiling FileWr.m3 > "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN > "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX > 2 errors encountered > st > > > Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, > hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGREAL so that it works immediately on NT386. > Same issues as above, breaks existing users. > > > Maybe relax the language some, so that e.g. > a:INTEGER; > b:LONGINT; > > b := a; > > just works, see if it helps make more code compile with the change? > > a := b is problematic of course, but what is wrong with b := a? > > - Jay > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 21:53:12 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 20:53:12 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , , , , , , , Message-ID: (Actually the first didn't build quite the whole tree, but very nearly; a small number of packages remained to be fixed). I avoided hijacking a different thread, so I'll say it here instead: I'm surprised we are ok with the runtime checks of INTEGER := LONGINT but not the very natural INTEGER + LONGINT => LONGINT. You first find what all the expression terms are assignable to, do the math there, and that is the result. You can even adopt that simple rule for MOD, though MOD is a "very reducing" function and it is statically knowable I believe that widening isn't really needed. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 20:45:23 +0000 CC: m3devel at elegosoft.com Subject: Re: [M3devel] what to do about file sizes being 32bits? I've sent various patches. I believe the first had no compiler changes and built the whole tree. The second had maximum compiler changes (except for FOR) and built the whole tree. The third had only assignability and built just libm3. To build the whole tree you'd pretty much add all of the first diff. A few lines could be saved but not much. Assignability doesn't buy very much. I can do that if you want: assignability and build the whole tree. But we do know just about what it looks like. - Jay From: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 09:30:00 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] what to do about file sizes being 32bits? I still want to see the patch... Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 On 10 Jan 2010, at 04:10, Jay K wrote: Just a note that the version with ORD and VAL sprinkled everywhere is compatible with every proposal, *except* removing LONGINT altogether. It is ugly and tedious, but it does seem to work. Can we go with it?? Maybe "clean it up" afterward, if the compiler allows more? You basically just search for "LONGINT" or "VAL" across the tree... - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Subject: RE: [M3devel] what to do about file sizes being 32bits? Date: Thu, 7 Jan 2010 11:22:37 +0000 I'm working on this.. Attached is what I have so far. Posix needs work. Most code continues to not work for files >4GB on 32bit, but it is a start. It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. I'm not sure if the ToProc/FromProc stuff should use INTEGER/CARDINAL or LONGINT. This gets as far as: == package C:\dev2\cm3.2\m3-obliq\obliqrt == +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 -DCM3_VERSION_TEXT=d5.8.2 - DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ --- building in NT386 --- ignoring ..\src\m3overrides \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB m3cfe: (Error) failed to find source or AST for interface 'WordRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Word.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis suppressed due to import errors m3cfe: (Error) failed to find source or AST for interface 'LongRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Long.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic analysis suppresse d due to import errors "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic analysis suppr Which is probably some other problem? - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 09:47:07 +0000 Subject: Re: [M3devel] what to do about file sizes being 32bits? I think I can fix everything in the cm3 tree if size is changed to LONGINT. Including Index(), Length(), Seek(). It involves *many* uses of VAL and ORD, and indeed, it would help if: INC(longint, integer) was legal, which seems perfectly ok. longint := integer ditto Most of the toplevel users will end up throwing in ORD, as they require files to fit in memory/addressspace. There is still the matter of this will break too much code out there. - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 06:59:31 +0000 Subject: [M3devel] what to do about file sizes being 32bits? File.i3: Status = RECORD type: Type; modificationTime: Time.T; size: CARDINAL (* oops... *) END; What to do? [0.. higher than 7FFFFFFF] doesn't "just work". higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, which presumably has some relationship to turning it into a LONGINT, which causes users to fail to compile LONGINT doesn't "just work" causes users to fail to compile stale imports -> compiling ProcessPosixCommon.i3 stale imports -> compiling ProcessPosixCommon.m3 stale imports -> compiling ProcessPosix.m3 stale imports -> compiling FileRd.i3 missing version stamps -> compiling FileRd.m3 "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN "../src/rw/FileRd.m3", line 140: types are not assignable 2 errors encountered stale imports -> compiling FileWr.i3 missing version stamps -> compiling FileWr.m3 "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX 2 errors encountered st Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, hope the damage isn't too great outside the cm3 tree? Change it to LONGREAL so that it works immediately on NT386. Same issues as above, breaks existing users. Maybe relax the language some, so that e.g. a:INTEGER; b:LONGINT; b := a; just works, see if it helps make more code compile with the change? a := b is problematic of course, but what is wrong with b := a? - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 22:00:15 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 21:00:15 +0000 Subject: [M3devel] Integer literals In-Reply-To: <95DC398D-37D2-4B11-98F7-ED87D1CC9895@cs.purdue.edu> References: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu>, , <95DC398D-37D2-4B11-98F7-ED87D1CC9895@cs.purdue.edu> Message-ID: Hm..these hardware conversions..yeah they do exist. But they are fast and lossless. Depending on the instruction set, they aren't even avoidable. e.g. x86 I think usually does double arithmetic. 68K maybe extended. But to be clear, they tend to be a single instruction each, load or move. Every INTEGER can be represented in a LONGINT, by sign extension. Every REAL can be represented as LONGREAL. And you know, INTEGER MOD INTEGER on IA64 uses conversion to floating point? I was surprised by that actually, stepping through some hash table code, but it is just the way it is. There's I guess no integer division and the floating point is done with 64 or more bits of precision, so it works. As long as conversion is fast and lossless..? - Jay From: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 15:51:17 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] Integer literals No! You're missing my whole point about representation. With what you are proposing here for the float types you will end up with implicit conversion operations performed in the hardware. The whole idea with explicit conversions is that programmers don't end up coding something that they have not transparently written. That is a fundamental and highly-valued design principle with Modula-3. We are not trying to reinvent C here. On 10 Jan 2010, at 15:43, Jay K wrote: Seems fine either way. Assignability gives us, which we were missing before, VAR a:LONGINT := 0; > (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, but they really > do have incompatible value representations). I keep seeing this and am surprised. Isn't it the case that REAL <= LONGREAL <= EXTENDED in terms of precision and range? LONGREAL can losslessly represent all the values that REAL can represent, and possibly more (yes); EXTENDED can losslessly representa ll the values that LONGREAL can represent, and possibly more (not); And then, if that is true, mixing should be allowed..widen any constituents in an expression to the widest type. I realize mixing floating point and integer is less natural, nothing about floating point is natural really, though on a 32bit platform LONGREAL can hold all INTEGERS.. - Jay From: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 15:23:28 -0500 To: m3devel at elegosoft.com Subject: [M3devel] Integer literals One thing I've really struggled with over the introduction of LONGINT is the need for distinct literal forms. This strikes me as odd, since literals are really just ways of writing values, rather than stating anything about how they should be represented. (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, but they really do have incompatible value representations). It strikes me that with checked assignability for INTEGER/LONGINT we could also potentially treat integer literals as essentially "untyped" (neither INTEGER nor LONGINT). (I still strongly resist going the route of having mixed type operands for arithmetic...) Here's how things would work with subrange types. A subrange written as currently [lo .. hi] would by default be assumed to have base type INTEGER. The constants lo/hi must both be in range for INTEGER. A subrange with base type LONGINT would be written explicitly: [lo .. hi] OF LONGINT The constants lo/hi must both be in range for LONGINT. We could also support the form: [lo .. hi] OF INTEGER just for consistency though the "OF INTEGER" qualification would be unnecessarily verbose. Here we are allowing the programmer to state explicitly what the base type of the subrange should be. Literals would be be range-checked when used as arithmetic operands or in assignment, with compile-time checks that they are in range ("compatible") with the types of the other operands or the destination of the assignment. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 22:06:06 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sun, 10 Jan 2010 16:06:06 -0500 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , , , , , , , Message-ID: Consider the following: + is overloaded to perform both INTEGER and LONGINT addition. When invoking + we choose the appropriate operation based on its operand types. Why do you think it is reasonable to assume that LONGINT+INTEGER should perform LONGINT + instead of INTEGER +? It is an *arbitrary* choice that you make which should give us pause in imposing that arbitrary choice in the language because it violates the principle of least surprise. Don't impose arbitrary choices that may confuse the programmer. Prohibiting mixed-operand operations prevents bugs arising when one programmer inadvertently assumes that his personal arbitrary choice is not the one that the language actually implements. Assignability is different in that the assignment operation is unambiguously tied to the type of its left-hand-side. Assignment forces a value into a particular representation -- that of the pre-allocated "storage" designated by the LHS. If the value is not compatible with that representation then we can raise a run-time error. On 10 Jan 2010, at 15:53, Jay K wrote: > (Actually the first didn't build quite the whole tree, but very nearly; > a small number of packages remained to be fixed). > > I avoided hijacking a different thread, so I'll say it here instead: > I'm surprised we are ok with the runtime checks of INTEGER := LONGINT > but not the very natural INTEGER + LONGINT => LONGINT. > You first find what all the expression terms are assignable to, do the math > there, and that is the result. You can even adopt that simple rule for MOD, > though MOD is a "very reducing" function and it is statically knowable > I believe that widening isn't really needed. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Sun, 10 Jan 2010 20:45:23 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > I've sent various patches. > I believe the first had no compiler changes and built the whole tree. > The second had maximum compiler changes (except for FOR) and built the whole tree. > The third had only assignability and built just libm3. > To build the whole tree you'd pretty much add all of the first diff. A few lines > could be saved but not much. Assignability doesn't buy very much. > I can do that if you want: assignability and build the whole tree. > But we do know just about what it looks like. > > - Jay > > > > From: hosking at cs.purdue.edu > Date: Sun, 10 Jan 2010 09:30:00 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > I still want to see the patch... > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 > > > > > On 10 Jan 2010, at 04:10, Jay K wrote: > > Just a note that the version with ORD and VAL sprinkled everywhere > is compatible with every proposal, *except* removing LONGINT altogether. > It is ugly and tedious, but it does seem to work. > > Can we go with it?? > > Maybe "clean it up" afterward, if the compiler allows more? > You basically just search for "LONGINT" or "VAL" across the tree... > > > - Jay > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Subject: RE: [M3devel] what to do about file sizes being 32bits? > Date: Thu, 7 Jan 2010 11:22:37 +0000 > > I'm working on this.. > Attached is what I have so far. > Posix needs work. > Most code continues to not work for files >4GB on 32bit, but it is a start. > It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. > Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. > I'm not sure if the ToProc/FromProc stuff should use INTEGER/CARDINAL or LONGINT. > > This gets as far as: > > == package C:\dev2\cm3.2\m3-obliq\obliqrt == > > +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 -DCM3_VERSION_TEXT=d5.8.2 - > DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ > --- building in NT386 --- > > ignoring ..\src\m3overrides > > \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB > m3cfe: (Error) failed to find source or AST for interface 'WordRep' > "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Word.i3]": semanti > c analysis suppressed due to import errors > "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis suppressed due > to import errors > m3cfe: (Error) failed to find source or AST for interface 'LongRep' > "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Long.i3]": semanti > c analysis suppressed due to import errors > "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic analysis suppresse > d due to import errors > "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic analysis suppr > > > Which is probably some other problem? > > > - Jay > > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 09:47:07 +0000 > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > I think I can fix everything in the cm3 tree if size is changed to LONGINT. > Including Index(), Length(), Seek(). > It involves *many* uses of VAL and ORD, and indeed, it would help if: > > > INC(longint, integer) was legal, which seems perfectly ok. > longint := integer ditto > > > Most of the toplevel users will end up throwing in ORD, as they > require files to fit in memory/addressspace. > > > There is still the matter of this will break too much code out there. > > > - Jay > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 06:59:31 +0000 > Subject: [M3devel] what to do about file sizes being 32bits? > > File.i3: > > > Status = RECORD > type: Type; > modificationTime: Time.T; > size: CARDINAL (* oops... *) > END; > > > What to do? > [0.. higher than 7FFFFFFF] doesn't "just work". > higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, > which presumably has some relationship to turning it into a LONGINT, which > causes users to fail to compile > > > LONGINT doesn't "just work" > causes users to fail to compile > > > stale imports -> compiling ProcessPosixCommon.i3 > stale imports -> compiling ProcessPosixCommon.m3 > stale imports -> compiling ProcessPosix.m3 > stale imports -> compiling FileRd.i3 > missing version stamps -> compiling FileRd.m3 > "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN > "../src/rw/FileRd.m3", line 140: types are not assignable > 2 errors encountered > stale imports -> compiling FileWr.i3 > missing version stamps -> compiling FileWr.m3 > "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN > "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX > 2 errors encountered > st > > > Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, > hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGREAL so that it works immediately on NT386. > Same issues as above, breaks existing users. > > > Maybe relax the language some, so that e.g. > a:INTEGER; > b:LONGINT; > > b := a; > > just works, see if it helps make more code compile with the change? > > a := b is problematic of course, but what is wrong with b := a? > > - Jay > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sun Jan 10 22:08:18 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sun, 10 Jan 2010 16:08:18 -0500 Subject: [M3devel] Fwd: CM3 development Inquiry. References: <20100110164332.0c09a257.dimonax@att.net> Message-ID: <5A44E4F2-AF0C-4241-BD11-4A8B0912A022@cs.purdue.edu> This guy is trying to subscribe to m3devel. Can someone help him? Begin forwarded message: > From: Chris > Date: 10 January 2010 16:43:32 EST > To: Tony Hosking > Subject: Re: CM3 development Inquiry. > > On Fri, 8 Jan 2010 13:01:21 -0500 > Tony Hosking wrote: > >> Did you manage to subscribe? > > I put in another subscription request just after your previous reply, and I'm still waiting. I wonder if the confirmation e-mail is getting through. Nonetheless, I'll keep trying. > > > -- > Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Jan 10 23:02:33 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 22:02:33 +0000 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , ,,, ,,, , , , , , , Message-ID: Is it really just me who finds the choices all fairly obvious? You do the math in the wider type. Is that really surprising? Am I just, like, brain washed with years of assumptions? That's what Rodney's proposal said. In the case of MOD and DIV, you can pause for thought and maybe make them return a narrower type, but if you just want to be simple and stay wide, that's ok. - Jay From: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 16:06:06 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] what to do about file sizes being 32bits? Consider the following: + is overloaded to perform both INTEGER and LONGINT addition. When invoking + we choose the appropriate operation based on its operand types. Why do you think it is reasonable to assume that LONGINT+INTEGER should perform LONGINT + instead of INTEGER +? It is an *arbitrary* choice that you make which should give us pause in imposing that arbitrary choice in the language because it violates the principle of least surprise. Don't impose arbitrary choices that may confuse the programmer. Prohibiting mixed-operand operations prevents bugs arising when one programmer inadvertently assumes that his personal arbitrary choice is not the one that the language actually implements. Assignability is different in that the assignment operation is unambiguously tied to the type of its left-hand-side. Assignment forces a value into a particular representation -- that of the pre-allocated "storage" designated by the LHS. If the value is not compatible with that representation then we can raise a run-time error. On 10 Jan 2010, at 15:53, Jay K wrote: (Actually the first didn't build quite the whole tree, but very nearly; a small number of packages remained to be fixed). I avoided hijacking a different thread, so I'll say it here instead: I'm surprised we are ok with the runtime checks of INTEGER := LONGINT but not the very natural INTEGER + LONGINT => LONGINT. You first find what all the expression terms are assignable to, do the math there, and that is the result. You can even adopt that simple rule for MOD, though MOD is a "very reducing" function and it is statically knowable I believe that widening isn't really needed. - Jay From: jay.krell at cornell.edu To: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 20:45:23 +0000 CC: m3devel at elegosoft.com Subject: Re: [M3devel] what to do about file sizes being 32bits? I've sent various patches. I believe the first had no compiler changes and built the whole tree. The second had maximum compiler changes (except for FOR) and built the whole tree. The third had only assignability and built just libm3. To build the whole tree you'd pretty much add all of the first diff. A few lines could be saved but not much. Assignability doesn't buy very much. I can do that if you want: assignability and build the whole tree. But we do know just about what it looks like. - Jay From: hosking at cs.purdue.edu Date: Sun, 10 Jan 2010 09:30:00 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] what to do about file sizes being 32bits? I still want to see the patch... Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 | Mobile +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 On 10 Jan 2010, at 04:10, Jay K wrote: Just a note that the version with ORD and VAL sprinkled everywhere is compatible with every proposal, *except* removing LONGINT altogether. It is ugly and tedious, but it does seem to work. Can we go with it?? Maybe "clean it up" afterward, if the compiler allows more? You basically just search for "LONGINT" or "VAL" across the tree... - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Subject: RE: [M3devel] what to do about file sizes being 32bits? Date: Thu, 7 Jan 2010 11:22:37 +0000 I'm working on this.. Attached is what I have so far. Posix needs work. Most code continues to not work for files >4GB on 32bit, but it is a start. It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an INTEGER to a LONGINT, as all INTEGER values fit. Similarly I should be able to compare a LONGINT to 0 directly, instead of 0L. I'm not sure if the ToProc/FromProc stuff should use INTEGER/CARDINAL or LONGINT. This gets as far as: == package C:\dev2\cm3.2\m3-obliq\obliqrt == +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 -DCM3_VERSION_TEXT=d5.8.2 - DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ --- building in NT386 --- ignoring ..\src\m3overrides \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB m3cfe: (Error) failed to find source or AST for interface 'WordRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Word.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis suppressed due to import errors m3cfe: (Error) failed to find source or AST for interface 'LongRep' "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word\Long.i3]": semanti c analysis suppressed due to import errors "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic analysis suppresse d due to import errors "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic analysis suppr Which is probably some other problem? - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 09:47:07 +0000 Subject: Re: [M3devel] what to do about file sizes being 32bits? I think I can fix everything in the cm3 tree if size is changed to LONGINT. Including Index(), Length(), Seek(). It involves *many* uses of VAL and ORD, and indeed, it would help if: INC(longint, integer) was legal, which seems perfectly ok. longint := integer ditto Most of the toplevel users will end up throwing in ORD, as they require files to fit in memory/addressspace. There is still the matter of this will break too much code out there. - Jay From: jay.krell at cornell.edu To: m3devel at elegosoft.com Date: Thu, 7 Jan 2010 06:59:31 +0000 Subject: [M3devel] what to do about file sizes being 32bits? File.i3: Status = RECORD type: Type; modificationTime: Time.T; size: CARDINAL (* oops... *) END; What to do? [0.. higher than 7FFFFFFF] doesn't "just work". higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" on the end, which presumably has some relationship to turning it into a LONGINT, which causes users to fail to compile LONGINT doesn't "just work" causes users to fail to compile stale imports -> compiling ProcessPosixCommon.i3 stale imports -> compiling ProcessPosixCommon.m3 stale imports -> compiling ProcessPosix.m3 stale imports -> compiling FileRd.i3 missing version stamps -> compiling FileRd.m3 "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN "../src/rw/FileRd.m3", line 140: types are not assignable 2 errors encountered stale imports -> compiling FileWr.i3 missing version stamps -> compiling FileWr.m3 "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX 2 errors encountered st Change it to LONGINT, fix all the callers, and hope the damage isn't too great outside the cm3 tree? Change it to LONGINT only for 32bit platforms, somehow author the cm3 tree to work either way, hope the damage isn't too great outside the cm3 tree? Change it to LONGREAL so that it works immediately on NT386. Same issues as above, breaks existing users. Maybe relax the language some, so that e.g. a:INTEGER; b:LONGINT; b := a; just works, see if it helps make more code compile with the change? a := b is problematic of course, but what is wrong with b := a? - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hendrik at topoi.pooq.com Sun Jan 10 23:11:37 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Sun, 10 Jan 2010 17:11:37 -0500 Subject: [M3devel] Integer literals In-Reply-To: References: <95DC398D-37D2-4B11-98F7-ED87D1CC9895@cs.purdue.edu> Message-ID: <20100110221137.GB16635@topoi.pooq.com> On Sun, Jan 10, 2010 at 09:00:15PM +0000, Jay K wrote: > > And you know, INTEGER MOD INTEGER on IA64 uses conversion to floating point? Just for clarity, do you mean the Itanium here? -- hendrik From jay.krell at cornell.edu Sun Jan 10 23:22:00 2010 From: jay.krell at cornell.edu (Jay K) Date: Sun, 10 Jan 2010 22:22:00 +0000 Subject: [M3devel] Integer literals In-Reply-To: <20100110221137.GB16635@topoi.pooq.com> References: <95DC398D-37D2-4B11-98F7-ED87D1CC9895@cs.purdue.edu>, , <20100110221137.GB16635@topoi.pooq.com> Message-ID: Yes of course. echo %PROCESSOR_ARCHITECTURE% - Jay > Date: Sun, 10 Jan 2010 17:11:37 -0500 > From: hendrik at topoi.pooq.com > To: m3devel at elegosoft.com > Subject: Re: [M3devel] Integer literals > > On Sun, Jan 10, 2010 at 09:00:15PM +0000, Jay K wrote: > > > > And you know, INTEGER MOD INTEGER on IA64 uses conversion to floating point? > > Just for clarity, do you mean the Itanium here? > > -- hendrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From jayk123 at hotmail.com Mon Jan 11 05:58:13 2010 From: jayk123 at hotmail.com (jayk123 at hotmail.com) Date: Sun, 10 Jan 2010 20:58:13 -0800 Subject: [M3devel] what to do about file sizes being 32bits? In-Reply-To: References: , , , , , , , , , , , , , , Message-ID: To repeat myself: you can reason about + via assignability, sort of. Of the two input types, you see which is assignable to which, and conceptually assign the inputs to two temporaries of that type. Assuming longint *not* assignable to integer, done. If it is assignable, pick the type that can guaranteeably hold all values of the two inputs. In terms of implict vs. explict..I fallback to my usual claim: what people already probably think of as simple very often is not. The "red flag" of "complexity", I find, is raised very quickly, when people just don't like something. I think there might be another way though. What if rd/wr users had to change *lots* of types from integer and cardinal to longint..and index by longint allowed? Maybe maybe that'd have a "pleasant" outcome. But still, given that NUMBER returns CARDINAL, still must end up mixing somehow, either via implicit or explicit conversion/assignment. Btw are C's rules really so different or complicated? Don't they look like "assignability" too? The one problem I know of is in comparison if "full range" unsigned types with signed types. There are two equally good/bad options: I think called "sign preserving" and "magnitude preserving" aka "magnitude losing" and "sign losing". Either a large positive number becomes negative or a negative number becomes a large positive. I believe avoidance of this problem is why CARDINAL is "half range". - Jay (phone) On Jan 10, 2010, at 2:02 PM, Jay K wrote: > Is it really just me who finds the choices all fairly obvious? > You do the math in the wider type. Is that really surprising? > Am I just, like, brain washed with years of assumptions? > That's what Rodney's proposal said. > In the case of MOD and DIV, you can pause for thought > and maybe make them return a narrower type, but > if you just want to be simple and stay wide, that's ok. > > - Jay > > > > From: hosking at cs.purdue.edu > Date: Sun, 10 Jan 2010 16:06:06 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > Consider the following: + is overloaded to perform both INTEGER and > LONGINT addition. When invoking + we choose the appropriate > operation based on its operand types. Why do you think it is > reasonable to assume that LONGINT+INTEGER should perform LONGINT + > instead of INTEGER +? It is an *arbitrary* choice that you make > which should give us pause in imposing that arbitrary choice in the > language because it violates the principle of least surprise. Don't > impose arbitrary choices that may confuse the programmer. > Prohibiting mixed-operand operations prevents bugs arising when one > programmer inadvertently assumes that his personal arbitrary choice > is not the one that the language actually implements. > > Assignability is different in that the assignment operation is > unambiguously tied to the type of its left-hand-side. Assignment > forces a value into a particular representation -- that of the pre- > allocated "storage" designated by the LHS. If the value is not > compatible with that representation then we can raise a run-time > error. > > On 10 Jan 2010, at 15:53, Jay K wrote: > > (Actually the first didn't build quite the whole tree, but very > nearly; > a small number of packages remained to be fixed). > > I avoided hijacking a different thread, so I'll say it here instead: > I'm surprised we are ok with the runtime checks of INTEGER := > LONGINT > but not the very natural INTEGER + LONGINT => LONGINT. > You first find what all the expression terms are assignable to, > do the math > there, and that is the result. You can even adopt that simple > rule for MOD, > though MOD is a "very reducing" function and it is statically > knowable > I believe that widening isn't really needed. > > - Jay > > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Sun, 10 Jan 2010 20:45:23 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > I've sent various patches. > I believe the first had no compiler changes and built the whole tree. > The second had maximum compiler changes (except for FOR) and built > the whole tree. > The third had only assignability and built just libm3. > To build the whole tree you'd pretty much add all of the first > diff. A few lines > could be saved but not much. Assignability doesn't buy very much. > I can do that if you want: assignability and build the whole tree. > But we do know just about what it looks like. > > - Jay > > > > From: hosking at cs.purdue.edu > Date: Sun, 10 Jan 2010 09:30:00 -0500 > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > I still want to see the patch... > > Antony Hosking | Associate Professor | Computer Science | Purdue > University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 > +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 +1 765 494 6001 > | Mobile +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 > +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 +1 765 427 5484 > > > > > On 10 Jan 2010, at 04:10, Jay K wrote: > > Just a note that the version with ORD and VAL sprinkled everywhere > is compatible with every proposal, *except* removing LONGINT > altogether. > It is ugly and tedious, but it does seem to work. > > Can we go with it?? > > Maybe "clean it up" afterward, if the compiler allows more? > You basically just search for "LONGINT" or "VAL" across the tree... > > > - Jay > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Subject: RE: [M3devel] what to do about file sizes being 32bits? > Date: Thu, 7 Jan 2010 11:22:37 +0000 > > I'm working on this.. > Attached is what I have so far. > Posix needs work. > Most code continues to not work for files >4GB on 32bit, but it is a > start. > It seems to me I shouldn't have o use VAL(i, LONGINT) to convert an > INTEGER to a LONGINT, as all INTEGER values fit. > Similarly I should be able to compare a LONGINT to 0 directly, > instead of 0L. > I'm not sure if the ToProc/FromProc stuff should use INTEGER/ > CARDINAL or LONGINT. > > This gets as far as: > > == package C:\dev2\cm3.2\m3-obliq\obliqrt == > > +++ C:\cm3\bin\cm3.exe -build -DROOT=C:/dev2/cm3.2 - > DCM3_VERSION_TEXT=d5.8.2 - > DCM3_VERSION_NUMBER=050802 -DCM3_LAST_CHANGED=2009-07-15 +++ > --- building in NT386 --- > > ignoring ..\src\m3overrides > > \cm3\bin\stubgen -v1 -sno ObValue.RemVar -T.M3IMPTAB > m3cfe: (Error) failed to find source or AST for interface 'WordRep' > "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word > \Word.i3]": semanti > c analysis suppressed due to import errors > "\cm3\pkg\m3core\src/text\Text.i3", line 16,0: semantic analysis > suppressed due > to import errors > m3cfe: (Error) failed to find source or AST for interface 'LongRep' > "\cm3\pkg\m3core\src/word\GenWord.ig[\cm3\pkg\m3core\src/word > \Long.i3]": semanti > c analysis suppressed due to import errors > "\cm3\pkg\m3core\src/float/IEEE\Real.i3", line 11,0: semantic > analysis suppresse > d due to import errors > "\cm3\pkg\m3core\src/float/IEEE\LongReal.i3", line 10,0: semantic > analysis suppr > > > Which is probably some other problem? > > > - Jay > > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 09:47:07 +0000 > Subject: Re: [M3devel] what to do about file sizes being 32bits? > > I think I can fix everything in the cm3 tree if size is changed to > LONGINT. > Including Index(), Length(), Seek(). > It involves *many* uses of VAL and ORD, and indeed, it would help if: > > > INC(longint, integer) was legal, which seems perfectly ok. > longint := integer ditto > > > Most of the toplevel users will end up throwing in ORD, as they > require files to fit in memory/addressspace. > > > There is still the matter of this will break too much code out there. > > > - Jay > > From: jay.krell at cornell.edu > To: m3devel at elegosoft.com > Date: Thu, 7 Jan 2010 06:59:31 +0000 > Subject: [M3devel] what to do about file sizes being 32bits? > > File.i3: > > > Status = RECORD > type: Type; > modificationTime: Time.T; > size: CARDINAL (* oops... *) > END; > > > What to do? > [0.. higher than 7FFFFFFF] doesn't "just work". > higher than 7FFFFFFFF is not legal on 32bit, unless you put "L" > on the end, > which presumably has some relationship to turning it into a > LONGINT, which > causes users to fail to compile > > > LONGINT doesn't "just work" > causes users to fail to compile > > > stale imports -> compiling ProcessPosixCommon.i3 > stale imports -> compiling ProcessPosixCommon.m3 > stale imports -> compiling ProcessPosix.m3 > stale imports -> compiling FileRd.i3 > missing version stamps -> compiling FileRd.m3 > "../src/rw/FileRd.m3", line 73: incompatible argument types: MIN > "../src/rw/FileRd.m3", line 140: types are not assignable > 2 errors encountered > stale imports -> compiling FileWr.i3 > missing version stamps -> compiling FileWr.m3 > "../src/rw/FileWr.m3", line 92: incompatible argument types: MIN > "../src/rw/FileWr.m3", line 108: incompatible argument types: MAX > 2 errors encountered > st > > > Change it to LONGINT, fix all the callers, and hope the damage isn't > too great outside the cm3 tree? > > > Change it to LONGINT only for 32bit platforms, somehow author the > cm3 tree to work either way, > hope the damage isn't too great outside the cm3 tree? > > > Change it to LONGREAL so that it works immediately on NT386. > Same issues as above, breaks existing users. > > > Maybe relax the language some, so that e.g. > a:INTEGER; > b:LONGINT; > > b := a; > > just works, see if it helps make more code compile with the change? > > a := b is problematic of course, but what is wrong with b := a? > > - Jay > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rcolebur at SCIRES.COM Mon Jan 11 07:11:52 2010 From: rcolebur at SCIRES.COM (Randy Coleburn) Date: Mon, 11 Jan 2010 01:11:52 -0500 Subject: [M3devel] the LONGINT proposal In-Reply-To: <73D2F123-F308-4210-9655-1F80F9A5C370@cs.purdue.edu> References: <20100110051218.2F3C42474001@birch.elegosoft.com> <73D2F123-F308-4210-9655-1F80F9A5C370@cs.purdue.edu> Message-ID: Tony: Sorry, I have been too long-winded here. To answer your questions succinctly: 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. 2. I think checked assignability gets us onto the slippery slope (see below). Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. Read on for the long-winded version... According to NELSON (SPwM3), ORD and VAL convert between enumerations and INTEGERs, and INTEGER is all integers represented by the implementation. So, the range of INTEGER is likely different for 8-bit, 16-bit, 32-bit, and 64-bit processors. Today we see 32-bit and 64-bit processors as predominant, but I remember the day when 8-bit and 16-bit were the norm. Someday we may see 128-bit processors as the norm. (I've been cleaning up my basement office and ran across a box of 8-inch floppy disks. When I showed them to my daughter she understood the meaning of "floppy" as opposed to the rigid 3.5-inch floppies of today. But, I digress.) On a 64-bit processor, this whole idea of LONGINT as 64-bits then becomes mute since INTEGER will be 64 bits also. But on a 16-bit machine (assuming we had an implementation for one) the native word size would be less than the 32-bits we seem to take for granted now. One problem is that one doesn't really know the range of LONGINT unless we define it as some number of bits. Rodney's proposal simply stated that LONGINT was at least as big as INTEGER but could be larger. So, on a 64-bit machine, are LONGINT and INTEGER really the same in terms of implementation?, whereas on a 32-bit the LONGINT would have an additional 32-bits more than INTEGER? What about a 128-bit machine? I say all this to point out the obvious, namely that LONGINT and INTEGER are different types. Therefore, IMO the language must make it clear how these different types interact. I would argue that x: LONGINT := 23; is wrong! The programmer should have to write x: LONGINT := 23L; instead. A subrange of LONGINT would be written as [23L..4200L] and would be a different type than the integer subrange [23..4200] even though the ranges are identical. Likewise, IMO mixed arithmetic with the compiler deciding what to do is wrong. The programmer should have to explicitly write conversions to a common type for arithmetic. I have no problem with extending the existing operators to deal with LONGINT; it's just that the result should be LONGINT. Given x: LONGINT := 49L; INC(x) yields 50L INC(x, 3L) yields 52L note that INC(x, 3) would be a syntax error since 3 is an INTEGER and x is a LONGINT (x + 20L) yields 69L note that (x + 20) would be a syntax error since 20 is an INTEGER and x is a LONGINT LAST(LONGINT) yields a LONGINT Now that I think about it more, I have a problem using ORD/VAL for the conversion since NELSON defines these as converting between enumerations and INTEGERs, and since LONGINT is a different type than INTEGER and quite possibly has a greater range than INTEGER. Is the proposal to also allow enumerations to use the range of LONGINT ? Enumerations currently are defined as having a range no greater than INTEGER. To extend them to LONGINT would lose the obvious performance benefits of keeping them same range as native INTEGER. Maybe we should invent new names for the conversions between INTEGER and LONGINT. Perhaps PROMOTE and DEMOTE or some such. These are probably bad names, but I use them below simply to illustrate (feel free to come up with better names): Given longInt: LONGINT; and int: INTEGER; int := DEMOTE(longInt); would perform the conversion from LONGINT to INTEGER and would give a runtime range check error if longInt is too big/small to fit in an INTEGER. longInt := PROMOTE(int) would always succeed in performing the conversion from INTEGER to LONGINT but would make the conversion explicit int + DEMOTE(longInt) would yield an INTEGER result with all arithmetic being done in the range of INTEGER longInt + PROMOTE(int) would yield a LONGINT result with all arithmetic being done in the range of LONGINT Now if we were to allow checked assignability (as Tony is leaning toward), I think we begin to get on the slippery slope. How far do we extend this to the point that it is not clear in the expression of the code what is happening? If I can write "int := longInt;" why not "int := 23L;" and why not "int := longInt + 57;" and is this different than "int := longInt + 57L;"? etc. etc. I agree the ORD/VAL syntax is ugly, so that is another reason (besides them applying to enumerations only) we should use different names for the INTEGER/LONGINT conversions. Sorry, I have been too long-winded here. To answer your questions succinctly: 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. 2. I think checked assignability gets us onto the slippery slope. Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. Regards, Randy Coleburn From: Tony Hosking [mailto:hosking at cs.purdue.edu] Sent: Sunday, January 10, 2010 3:43 PM To: Randy Coleburn Cc: m3devel Subject: Re: [M3devel] the LONGINT proposal Hi Randy, As someone who has actually written Modula-3 programs for a living your opinions are always highly valued. I agree with you in principle and aims, except for requiring overflow to be a checked run-time error. The language definition already has a mechanism for handling this in the require FloatMode interface. It is not something that the compiler should be involved in. I also just now raised a question about perhaps having integer literals adapt their type to the context in which they are used. I should point out that the current mainline implementation does exactly what you propose (except overflow checking). It captures the fundamental spirit of Rodney's proposal but does not permit mixed arithmetic or assignment. Can I ask what your issue is w.r.to checked assignability? I am still leaning in favor. It is not much different from assignment from an INTEGER to a subrange, which requires no explicit check, though of course there is a run-time range check. Having programmers explicitly write: x: INTEGER := ORD(longint, INTEGER); seems unnecessary when they could just write x: INTEGER := longint; This is similar in spirit to: x: [lo..hi] := integer; On 10 Jan 2010, at 15:00, Randy Coleburn wrote: I've been trying to follow along on this topic. Here are my thoughts: 1. LONGINT should be a distinct type different from INTEGER. 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. 3. Overflow should be a checked run-time error, not silently wrapped around. 4. WRT assignability, I think explicit conversions should be used. These statements may make me unpopular with some who don't like to type much, but I've always hated the tradeoff of understandability for brevity in expression. The important thing is not how fast we can type up a program, it is rather how hard is it to make a mistake. I think the spirit of Modula-3 is that the language makes you a better programmer by forcing you to make your intentions explicit rather than relying on the compiler to infer your intentions. We need correct and maintainable software, especially at the systems level. Whatever is decided about LONGINT, we need to keep to the original design tenants of the language. And yes, I do think we need a LONGINT type, not just to deal with large file sizes. But even for long-lived readers/writers, whatever type you choose for the index will eventually be insufficient, so you have to code for the possibility that the range of the long lived reader/writer exceeds the range of your index type. That is just good programming. I think sometimes that the new generation of programmers has been warped by what I call the "Microsoft Mentality" where you must expect that you need to reboot/restart every so often to maintain proper performance. Programs should be written to run forever or until their job is completed or they are commanded to stop. As "we" begin to converge on the design changes, I like having something concrete to look at, ala Rodney's proposal. Can we take that and keep tweaking it in these emails until we reach a final version acceptable to all? To me this keeps the discussion focused rather than the many different emails. Thus, what I am trying to say is put forth a numbered proposal and each subsequent email must show adjustment to that proposal rather than just a bunch of emails discussing various aspects. Perhaps we should vote on each proposed change, then decide to call a final vote on the whole thing. Who should be involved in such votes? Right now the main persons on the thread are Tony, Jay, Rodney, Mika, Hendrik, Olaf, John, and me. My two cents. Regards, Randy Coleburn -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elegosoft.com Mon Jan 11 10:51:34 2010 From: wagner at elegosoft.com (Olaf Wagner) Date: Mon, 11 Jan 2010 10:51:34 +0100 Subject: [M3devel] Truncation problem fixed, was: Re: another longint variant In-Reply-To: References: , , <69E00635-6D2B-4079-82DE-8FE041ED5095@cs.purdue.edu>, , Message-ID: <20100111105134.4zr9fs0lc00wsok8@mail.elegosoft.com> Quoting Jay K : > [replacing periods with semicolons to avoid truncation..] Mike has made a change some days ago that should fix the truncation of mails at certain periods. If anybody experiences this again, you should let him know. Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From wagner at elegosoft.com Mon Jan 11 11:52:57 2010 From: wagner at elegosoft.com (Olaf Wagner) Date: Mon, 11 Jan 2010 11:52:57 +0100 Subject: [M3devel] Fwd: CM3 development Inquiry. In-Reply-To: <5A44E4F2-AF0C-4241-BD11-4A8B0912A022@cs.purdue.edu> References: <20100110164332.0c09a257.dimonax@att.net> <5A44E4F2-AF0C-4241-BD11-4A8B0912A022@cs.purdue.edu> Message-ID: <20100111115257.d437knapzgocgc0g@mail.elegosoft.com> Quoting Tony Hosking : > This guy is trying to subscribe to m3devel. Can someone help him? > > Begin forwarded message: > >> From: Chris >> Date: 10 January 2010 16:43:32 EST >> To: Tony Hosking >> Subject: Re: CM3 development Inquiry. >> >> On Fri, 8 Jan 2010 13:01:21 -0500 >> Tony Hosking wrote: >> >>> Did you manage to subscribe? >> >> I put in another subscription request just after your previous >> reply, and I'm still waiting. I wonder if the confirmation e-mail >> is getting through. Nonetheless, I'll keep trying. Unfortunately the address does not work: This is the mail system at host mx0.elegosoft.com. I'm sorry to have to inform you that your message could not be delivered to one or more recipients. It's attached below. For further assistance, please send mail to postmaster. If you do so, please include this problem report. You can delete your own text from the attached returned message. The mail system : host scc-mailrelay.att.net[204.127.208.75] said: 521-88.198.54.133 blocked by sbc:blacklist.mailrelay.att.net. 521 DNSRBL: Blocked for abuse. See http://att.net/blocks (in reply to MAIL FROM command) If he really wants to join, he needs another mail address, but I cannot tell him that. Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Mon Jan 11 13:17:56 2010 From: jay.krell at cornell.edu (Jay K) Date: Mon, 11 Jan 2010 12:17:56 +0000 Subject: [M3devel] some more "crazy" proposals Message-ID: 1) change file/rd/wr sizes to be BigInteger.T and/or 2) Introduce SeekL, IndexL, StatusL, etc. default implementation calls Seek/Index/Status and does checked truncation. Clients gradually port to LONGINT or BigInteger.T. Completely source compatible. 3) BigInteger.T is The multiple-INTEGER precision type?? No compiler/language change?? I might try these out, and then go the extra step and port the file dialog to avoid the exception.. see what it all looks like... - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Mon Jan 11 13:14:06 2010 From: jay.krell at cornell.edu (Jay K) Date: Mon, 11 Jan 2010 12:14:06 +0000 Subject: [M3devel] the LONGINT proposal In-Reply-To: References: <20100110051218.2F3C42474001@birch.elegosoft.com>, , <73D2F123-F308-4210-9655-1F80F9A5C370@cs.purdue.edu>, Message-ID: Randy I won't cover everything but on some of these matters you are not alone. In particular, INTEGER and LONGINT are different types, in the current implementation, and I think in all proposals. It is quite striking how the current implemtation makes them completely different. However many proposals do allow assignability which does make it a bit blurry to a user what different types mean. One thing that I bet will always remain though, is that VAR parameters of INTEGER cannot "bind" to LONGINT, and vice versa. The equivalent is true in C and C++: pointers to int and long cannot be interchanged, without a cast, even if int and long are both 32bit. That is, in C and C++, int and long are different types, just as in Modula-3, INTEGER and LONGINT are different types. Which goes to show one of my agendas: C isn't as bad as people think. It isn't safe, granted. There is no formal module system, but people are actually usually rigorous in their use of the informal system. As well, one of the goals I have espoused is that UNSAFE Modula-3 be not more unsafe than C. Which is why I don't like procedures to return ADDRESS and expect every caller to cast/loophole -- that is just more unsafe than things should be. I have some familiarity with 8 and 16 bit integers. We can perhaps claim that there is a hypothetical system with 16bit INTEGER and 32bit LONGINT? And that our proposals do work in such a system? There is some disagreement floating around apparently on even what to call the INTEGER <=> LONGINT conversions. Currently ORD converts to INTEGER. Randy's proposal I believe converts to the underlying type: INTEGER or LONGINT. And I think uses VAL(expr, INTEGER or LONGINT) to convert to INTEGER or LONGINT. I believe I saw a proposal that the converesions be named after the type: INTEGER(expr), LONGINT(expr). That kind of smacks to me of "too hard to search for". Here is a crazy verbose suggestion: LOOPHOLE(integer or subrange or enumeration or longint, INTEGER or LONGINT) and allow it in safe modules? At least it is existing syntax with roughly the desired meaning, except that LOOPHOLE is and sounds unsafe. CAST(expr, type) CONVERT(expr, type) ? I'm just making up words here of course. VAL or ORD seem sufficient, esp. if you can specify the type. gotta go, - Jay From: rcolebur at SCIRES.COM To: hosking at cs.purdue.edu Date: Mon, 11 Jan 2010 01:11:52 -0500 CC: m3devel at elegosoft.com Subject: Re: [M3devel] the LONGINT proposal Tony: Sorry, I have been too long-winded here. To answer your questions succinctly: 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. 2. I think checked assignability gets us onto the slippery slope (see below). Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. Read on for the long-winded version? According to NELSON (SPwM3), ORD and VAL convert between enumerations and INTEGERs, and INTEGER is all integers represented by the implementation. So, the range of INTEGER is likely different for 8-bit, 16-bit, 32-bit, and 64-bit processors. Today we see 32-bit and 64-bit processors as predominant, but I remember the day when 8-bit and 16-bit were the norm. Someday we may see 128-bit processors as the norm. (I?ve been cleaning up my basement office and ran across a box of 8-inch floppy disks. When I showed them to my daughter she understood the meaning of ?floppy? as opposed to the rigid 3.5-inch floppies of today. But, I digress.) On a 64-bit processor, this whole idea of LONGINT as 64-bits then becomes mute since INTEGER will be 64 bits also. But on a 16-bit machine (assuming we had an implementation for one) the native word size would be less than the 32-bits we seem to take for granted now. One problem is that one doesn?t really know the range of LONGINT unless we define it as some number of bits. Rodney?s proposal simply stated that LONGINT was at least as big as INTEGER but could be larger. So, on a 64-bit machine, are LONGINT and INTEGER really the same in terms of implementation?, whereas on a 32-bit the LONGINT would have an additional 32-bits more than INTEGER? What about a 128-bit machine? I say all this to point out the obvious, namely that LONGINT and INTEGER are different types. Therefore, IMO the language must make it clear how these different types interact. I would argue that x: LONGINT := 23; is wrong! The programmer should have to write x: LONGINT := 23L; instead. A subrange of LONGINT would be written as [23L..4200L] and would be a different type than the integer subrange [23..4200] even though the ranges are identical. Likewise, IMO mixed arithmetic with the compiler deciding what to do is wrong. The programmer should have to explicitly write conversions to a common type for arithmetic. I have no problem with extending the existing operators to deal with LONGINT; it?s just that the result should be LONGINT. Given x: LONGINT := 49L; INC(x) yields 50L INC(x, 3L) yields 52L note that INC(x, 3) would be a syntax error since 3 is an INTEGER and x is a LONGINT (x + 20L) yields 69L note that (x + 20) would be a syntax error since 20 is an INTEGER and x is a LONGINT LAST(LONGINT) yields a LONGINT Now that I think about it more, I have a problem using ORD/VAL for the conversion since NELSON defines these as converting between enumerations and INTEGERs, and since LONGINT is a different type than INTEGER and quite possibly has a greater range than INTEGER. Is the proposal to also allow enumerations to use the range of LONGINT ? Enumerations currently are defined as having a range no greater than INTEGER. To extend them to LONGINT would lose the obvious performance benefits of keeping them same range as native INTEGER. Maybe we should invent new names for the conversions between INTEGER and LONGINT. Perhaps PROMOTE and DEMOTE or some such. These are probably bad names, but I use them below simply to illustrate (feel free to come up with better names): Given longInt: LONGINT; and int: INTEGER; int := DEMOTE(longInt); would perform the conversion from LONGINT to INTEGER and would give a runtime range check error if longInt is too big/small to fit in an INTEGER. longInt := PROMOTE(int) would always succeed in performing the conversion from INTEGER to LONGINT but would make the conversion explicit int + DEMOTE(longInt) would yield an INTEGER result with all arithmetic being done in the range of INTEGER longInt + PROMOTE(int) would yield a LONGINT result with all arithmetic being done in the range of LONGINT Now if we were to allow checked assignability (as Tony is leaning toward), I think we begin to get on the slippery slope. How far do we extend this to the point that it is not clear in the expression of the code what is happening? If I can write ?int := longInt;? why not ?int := 23L;? and why not ?int := longInt + 57;? and is this different than ?int := longInt + 57L;?? etc. etc. I agree the ORD/VAL syntax is ugly, so that is another reason (besides them applying to enumerations only) we should use different names for the INTEGER/LONGINT conversions. Sorry, I have been too long-winded here. To answer your questions succinctly: 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. 2. I think checked assignability gets us onto the slippery slope. Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. Regards, Randy Coleburn From: Tony Hosking [mailto:hosking at cs.purdue.edu] Sent: Sunday, January 10, 2010 3:43 PM To: Randy Coleburn Cc: m3devel Subject: Re: [M3devel] the LONGINT proposal Hi Randy, As someone who has actually written Modula-3 programs for a living your opinions are always highly valued. I agree with you in principle and aims, except for requiring overflow to be a checked run-time error. The language definition already has a mechanism for handling this in the require FloatMode interface. It is not something that the compiler should be involved in. I also just now raised a question about perhaps having integer literals adapt their type to the context in which they are used. I should point out that the current mainline implementation does exactly what you propose (except overflow checking). It captures the fundamental spirit of Rodney's proposal but does not permit mixed arithmetic or assignment. Can I ask what your issue is w.r.to checked assignability? I am still leaning in favor. It is not much different from assignment from an INTEGER to a subrange, which requires no explicit check, though of course there is a run-time range check. Having programmers explicitly write: x: INTEGER := ORD(longint, INTEGER); seems unnecessary when they could just write x: INTEGER := longint; This is similar in spirit to: x: [lo..hi] := integer; On 10 Jan 2010, at 15:00, Randy Coleburn wrote: I've been trying to follow along on this topic. Here are my thoughts: 1. LONGINT should be a distinct type different from INTEGER. 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. 3. Overflow should be a checked run-time error, not silently wrapped around. 4. WRT assignability, I think explicit conversions should be used. These statements may make me unpopular with some who don't like to type much, but I've always hated the tradeoff of understandability for brevity in expression. The important thing is not how fast we can type up a program, it is rather how hard is it to make a mistake. I think the spirit of Modula-3 is that the language makes you a better programmer by forcing you to make your intentions explicit rather than relying on the compiler to infer your intentions. We need correct and maintainable software, especially at the systems level. Whatever is decided about LONGINT, we need to keep to the original design tenants of the language. And yes, I do think we need a LONGINT type, not just to deal with large file sizes. But even for long-lived readers/writers, whatever type you choose for the index will eventually be insufficient, so you have to code for the possibility that the range of the long lived reader/writer exceeds the range of your index type. That is just good programming. I think sometimes that the new generation of programmers has been warped by what I call the "Microsoft Mentality" where you must expect that you need to reboot/restart every so often to maintain proper performance. Programs should be written to run forever or until their job is completed or they are commanded to stop. As "we" begin to converge on the design changes, I like having something concrete to look at, ala Rodney's proposal. Can we take that and keep tweaking it in these emails until we reach a final version acceptable to all? To me this keeps the discussion focused rather than the many different emails. Thus, what I am trying to say is put forth a numbered proposal and each subsequent email must show adjustment to that proposal rather than just a bunch of emails discussing various aspects. Perhaps we should vote on each proposed change, then decide to call a final vote on the whole thing. Who should be involved in such votes? Right now the main persons on the thread are Tony, Jay, Rodney, Mika, Hendrik, Olaf, John, and me. My two cents. Regards, Randy Coleburn -------------- next part -------------- An HTML attachment was scrubbed... URL: From hendrik at topoi.pooq.com Mon Jan 11 17:23:01 2010 From: hendrik at topoi.pooq.com (hendrik at topoi.pooq.com) Date: Mon, 11 Jan 2010 11:23:01 -0500 Subject: [M3devel] the LONGINT proposal In-Reply-To: References: Message-ID: <20100111162301.GA23072@topoi.pooq.com> On Mon, Jan 11, 2010 at 12:14:06PM +0000, Jay K wrote: > > There is some disagreement floating around apparently on even what > to call the INTEGER <=> LONGINT conversions. > Currently ORD converts to INTEGER. > Randy's proposal I believe converts to the underlying type: INTEGER or LONGINT. > And I think uses VAL(expr, INTEGER or LONGINT) to convert to INTEGER or LONGINT. > > > I believe I saw a proposal that the converesions be named after the type: > INTEGER(expr), LONGINT(expr). > > That kind of smacks to me of "too hard to search for". > > Here is a crazy verbose suggestion: > LOOPHOLE(integer or subrange or enumeration or longint, INTEGER or LONGINT) > > and allow it in safe modules? > At least it is existing syntax with roughly the desired meaning, > except that LOOPHOLE is and sounds unsafe. > > CAST(expr, type) > CONVERT(expr, type) > ? > > I'm just making up words here of course. > VAL or ORD seem sufficient, esp. if you can specify the type. NARROW? WIDEN? And TRUNCATE if you really want to chop off the high-order bits without overflow check? -- hendrik From hosking at cs.purdue.edu Mon Jan 11 18:12:25 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 12:12:25 -0500 Subject: [M3devel] Fwd: CM3 development Inquiry. In-Reply-To: <20100111115257.d437knapzgocgc0g@mail.elegosoft.com> References: <20100110164332.0c09a257.dimonax@att.net> <5A44E4F2-AF0C-4241-BD11-4A8B0912A022@cs.purdue.edu> <20100111115257.d437knapzgocgc0g@mail.elegosoft.com> Message-ID: <9997AE9B-BB65-4B2E-9528-D002583C8B97@cs.purdue.edu> Actually, that diagnostic indicates that scc-mailrelay.att.net is blocking messages from the Elegosoft mail server (it is blacklisted!). Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On 11 Jan 2010, at 05:52, Olaf Wagner wrote: > Quoting Tony Hosking : > >> This guy is trying to subscribe to m3devel. Can someone help him? >> >> Begin forwarded message: >> >>> From: Chris >>> Date: 10 January 2010 16:43:32 EST >>> To: Tony Hosking >>> Subject: Re: CM3 development Inquiry. >>> >>> On Fri, 8 Jan 2010 13:01:21 -0500 >>> Tony Hosking wrote: >>> >>>> Did you manage to subscribe? >>> >>> I put in another subscription request just after your previous reply, and I'm still waiting. I wonder if the confirmation e-mail is getting through. Nonetheless, I'll keep trying. > > Unfortunately the address does not work: > > This is the mail system at host mx0.elegosoft.com. > > I'm sorry to have to inform you that your message could not > be delivered to one or more recipients. It's attached below. > > For further assistance, please send mail to postmaster. > > If you do so, please include this problem report. You can > delete your own text from the attached returned message. > > The mail system > > : host scc-mailrelay.att.net[204.127.208.75] said: > 521-88.198.54.133 blocked by sbc:blacklist.mailrelay.att.net. 521 DNSRBL: > Blocked for abuse. See http://att.net/blocks (in reply to MAIL FROM > command) > > If he really wants to join, he needs another mail address, but I cannot > tell him that. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Mon Jan 11 18:32:13 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 12:32:13 -0500 Subject: [M3devel] the LONGINT proposal In-Reply-To: References: <20100110051218.2F3C42474001@birch.elegosoft.com> <73D2F123-F308-4210-9655-1F80F9A5C370@cs.purdue.edu> Message-ID: <2158B017-4405-40B6-A750-FAD2BAA88BCB@cs.purdue.edu> Quick summary: I agree, and you seem to be supporting the status quo (other than your discomfort with ORD/VAL) as defined at: http://www.cs.purdue.edu/homes/hosking/m3/reference/ On 11 Jan 2010, at 01:11, Randy Coleburn wrote: > Tony: > > Sorry, I have been too long-winded here. To answer your questions succinctly: > > 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. Agreed. > > 2. I think checked assignability gets us onto the slippery slope (see below). Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. > > Read on for the long-winded version? > > According to NELSON (SPwM3), ORD and VAL convert between enumerations and INTEGERs, and INTEGER is all integers represented by the implementation. So, the range of INTEGER is likely different for 8-bit, 16-bit, 32-bit, and 64-bit processors. > > Today we see 32-bit and 64-bit processors as predominant, but I remember the day when 8-bit and 16-bit were the norm. Someday we may see 128-bit processors as the norm. > > (I?ve been cleaning up my basement office and ran across a box of 8-inch floppy disks. When I showed them to my daughter she understood the meaning of ?floppy? as opposed to the rigid 3.5-inch floppies of today. But, I digress.) > > On a 64-bit processor, this whole idea of LONGINT as 64-bits then becomes mute since INTEGER will be 64 bits also. But on a 16-bit machine (assuming we had an implementation for one) the native word size would be less than the 32-bits we seem to take for granted now. > > One problem is that one doesn?t really know the range of LONGINT unless we define it as some number of bits. Rodney?s proposal simply stated that LONGINT was at least as big as INTEGER but could be larger. So, on a 64-bit machine, are LONGINT and INTEGER really the same in terms of implementation?, whereas on a 32-bit the LONGINT would have an additional 32-bits more than INTEGER? What about a 128-bit machine? What's wrong with using FIRST(LONGINT) and LAST(LONGINT) to determine the range? This is currently implemented. On a 64-bit machine the types LONGINT and INTEGER are still distinct in the current implementation, so cannot be assigned, though they do happen to have the same underlying representation. > I say all this to point out the obvious, namely that LONGINT and INTEGER are different types. Correct. The current implementation treats them as completely separate. > Therefore, IMO the language must make it clear how these different types interact. > > I would argue that > x: LONGINT := 23; > is wrong! The programmer should have to write > x: LONGINT := 23L; > instead. This is what we currently implement. > A subrange of LONGINT would be written as [23L..4200L] and would be a different type than the integer subrange [23..4200] even though the ranges are identical. Also what we currently implement. > Likewise, IMO mixed arithmetic with the compiler deciding what to do is wrong. The programmer should have to explicitly write conversions to a common type for arithmetic. I agree, and this is the current implementation. > I have no problem with extending the existing operators to deal with LONGINT; it?s just that the result should be LONGINT. > Given x: LONGINT := 49L; > INC(x) yields 50L > INC(x, 3L) yields 52L > note that INC(x, 3) would be a syntax error since 3 is an INTEGER and x is a LONGINT > (x + 20L) yields 69L > note that (x + 20) would be a syntax error since 20 is an INTEGER and x is a LONGINT > LAST(LONGINT) yields a LONGINT This is exactly the current implementation. > Now that I think about it more, I have a problem using ORD/VAL for the conversion since NELSON defines these as converting between enumerations and INTEGERs, and since LONGINT is a different type than INTEGER and quite possibly has a greater range than INTEGER. Is the proposal to also allow enumerations to use the range of LONGINT ? Enumerations currently are defined as having a range no greater than INTEGER. To extend them to LONGINT would lose the obvious performance benefits of keeping them same range as native INTEGER. I'm not sure that the current implementation conflicts with the definition of ORD/VAL. What we currently permit is ORD(LONGINT) to do a *checked* conversion of a LONGINT to an INTEGER. The optional type parameter of VAL can be LONGINT, which permits conversion of INTEGER to LONGINT. I don't see how these conflict with the intention of ORD/VAL. You can see the language spec for what is currently implemented at: http://www.cs.purdue.edu/~hosking/m3/reference/. > Maybe we should invent new names for the conversions between INTEGER and LONGINT. Perhaps PROMOTE and DEMOTE or some such. These are probably bad names, but I use them below simply to illustrate (feel free to come up with better names): > Given longInt: LONGINT; and int: INTEGER; > int := DEMOTE(longInt); would perform the conversion from LONGINT to INTEGER and would give a runtime range check error if longInt is too big/small to fit in an INTEGER. > longInt := PROMOTE(int) would always succeed in performing the conversion from INTEGER to LONGINT but would make the conversion explicit > int + DEMOTE(longInt) would yield an INTEGER result with all arithmetic being done in the range of INTEGER > longInt + PROMOTE(int) would yield a LONGINT result with all arithmetic being done in the range of LONGINT I think ORD/VAL suffice... > Now if we were to allow checked assignability (as Tony is leaning toward), I think we begin to get on the slippery slope. How far do we extend this to the point that it is not clear in the expression of the code what is happening? If I can write ?int := longInt;? why not ?int := 23L;? and why not ?int := longInt + 57;? and is this different than ?int := longInt + 57L;?? etc. etc. > > I agree the ORD/VAL syntax is ugly, so that is another reason (besides them applying to enumerations only) we should use different names for the INTEGER/LONGINT conversions. > > Sorry, I have been too long-winded here. To answer your questions succinctly: > > 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. > > 2. I think checked assignability gets us onto the slippery slope. Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. > > Regards, > Randy Coleburn > > From: Tony Hosking [mailto:hosking at cs.purdue.edu] > Sent: Sunday, January 10, 2010 3:43 PM > To: Randy Coleburn > Cc: m3devel > Subject: Re: [M3devel] the LONGINT proposal > > Hi Randy, > > As someone who has actually written Modula-3 programs for a living your opinions are always highly valued. I agree with you in principle and aims, except for requiring overflow to be a checked run-time error. The language definition already has a mechanism for handling this in the require FloatMode interface. It is not something that the compiler should be involved in. I also just now raised a question about perhaps having integer literals adapt their type to the context in which they are used. > > I should point out that the current mainline implementation does exactly what you propose (except overflow checking). It captures the fundamental spirit of Rodney's proposal but does not permit mixed arithmetic or assignment. Can I ask what your issue is w.r.to checked assignability? I am still leaning in favor. It is not much different from assignment from an INTEGER to a subrange, which requires no explicit check, though of course there is a run-time range check. Having programmers explicitly write: > > x: INTEGER := ORD(longint, INTEGER); > > seems unnecessary when they could just write > > x: INTEGER := longint; > > This is similar in spirit to: > > x: [lo..hi] := integer; > > > On 10 Jan 2010, at 15:00, Randy Coleburn wrote: > > > I've been trying to follow along on this topic. > > Here are my thoughts: > > 1. LONGINT should be a distinct type different from INTEGER. > > 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. > > 3. Overflow should be a checked run-time error, not silently wrapped around. > > 4. WRT assignability, I think explicit conversions should be used. > > These statements may make me unpopular with some who don't like to type much, but I've always hated the tradeoff of understandability for brevity in expression. > > The important thing is not how fast we can type up a program, it is rather how hard is it to make a mistake. I think the spirit of Modula-3 is that the language makes you a better programmer by forcing you to make your intentions explicit rather than relying on the compiler to infer your intentions. We need correct and maintainable software, especially at the systems level. Whatever is decided about LONGINT, we need to keep to the original design tenants of the language. > > And yes, I do think we need a LONGINT type, not just to deal with large file sizes. > > But even for long-lived readers/writers, whatever type you choose for the index will eventually be insufficient, so you have to code for the possibility that the range of the long lived reader/writer exceeds the range of your index type. That is just good programming. > > I think sometimes that the new generation of programmers has been warped by what I call the "Microsoft Mentality" where you must expect that you need to reboot/restart every so often to maintain proper performance. Programs should be written to run forever or until their job is completed or they are commanded to stop. > > As "we" begin to converge on the design changes, I like having something concrete to look at, ala Rodney's proposal. Can we take that and keep tweaking it in these emails until we reach a final version acceptable to all? To me this keeps the discussion focused rather than the many different emails. Thus, what I am trying to say is put forth a numbered proposal and each subsequent email must show adjustment to that proposal rather than just a bunch of emails discussing various aspects. Perhaps we should vote on each proposed change, then decide to call a final vote on the whole thing. Who should be involved in such votes? Right now the main persons on the thread are Tony, Jay, Rodney, Mika, Hendrik, Olaf, John, and me. > > My two cents. > > Regards, > Randy Coleburn > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Mon Jan 11 18:42:00 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 12:42:00 -0500 Subject: [M3devel] the LONGINT proposal In-Reply-To: References: <20100110051218.2F3C42474001@birch.elegosoft.com>, , <73D2F123-F308-4210-9655-1F80F9A5C370@cs.purdue.edu>, Message-ID: <90520DA3-BD5C-494F-875B-F77910088E0B@cs.purdue.edu> On 11 Jan 2010, at 07:14, Jay K wrote: > Randy I won't cover everything but on some of these matters you are not alone. > In particular, INTEGER and LONGINT are different types, in the current > implementation, and I think in all proposals. > > > It is quite striking how the current implemtation makes them completely different. > However many proposals do allow assignability which does make it a bit > blurry to a user what different types mean. > One thing that I bet will always remain though, is that VAR parameters of INTEGER > cannot "bind" to LONGINT, and vice versa. > The equivalent is true in C and C++: pointers to int and long cannot be interchanged, > without a cast, even if int and long are both 32bit. > That is, in C and C++, int and long are different types, just as in Modula-3, > INTEGER and LONGINT are different types. But C has a much looser design philosophy than Modula-3. We should not compromise Modula-3 by veering towards C. > Which goes to show one of my agendas: C isn't as bad as people think. > It isn't safe, granted. There is no formal module system, but > people are actually usually rigorous in their use of the informal system. > As well, one of the goals I have espoused is that UNSAFE Modula-3 be > not more unsafe than C. Which is why I don't like procedures to return ADDRESS > and expect every caller to cast/loophole -- that is just more unsafe than things should be. > > > I have some familiarity with 8 and 16 bit integers. > We can perhaps claim that there is a hypothetical system > with 16bit INTEGER and 32bit LONGINT? > And that our proposals do work in such a system? > > > There is some disagreement floating around apparently on even what > to call the INTEGER <=> LONGINT conversions. > Currently ORD converts to INTEGER. I suppose ORD could convert to the underlying type, but given the intention that it be used to convert from an enumeration to an integer, then I think hardwiring it to return INTEGER is OK, since no enumeration will/should contain more elements than can be indexed by an INTEGER. On the other hand, I see no real problem if ORD(longint) returns LONGINT. It just means you have to do one more step to get an integer using VAL. > Randy's proposal I believe converts to the underlying type: INTEGER or LONGINT. > And I think uses VAL(expr, INTEGER or LONGINT) to convert to INTEGER or LONGINT. Yes, this is what we also currently implement. > I believe I saw a proposal that the converesions be named after the type: > INTEGER(expr), LONGINT(expr). I proposed that originally, but then decided that reusing VAL seemed much more intuitive. After all, we are asking to treat a typed expression in one domain as a *value* in some other type domain, so long as the value has a representative in that domain. > That kind of smacks to me of "too hard to search for". > > Here is a crazy verbose suggestion: > LOOPHOLE(integer or subrange or enumeration or longint, INTEGER or LONGINT) LOOPHOLE implies an unsafe operation! > and allow it in safe modules? Yuck!!!!!!!!!!!!!!!! > At least it is existing syntax with roughly the desired meaning, > except that LOOPHOLE is and sounds unsafe. I vote we stick with VAL. > CAST(expr, type) > CONVERT(expr, type) > ? Yuck! > I'm just making up words here of course. > VAL or ORD seem sufficient, esp. if you can specify the type. Agreed! > > gotta go, > - Jay > > > From: rcolebur at SCIRES.COM > To: hosking at cs.purdue.edu > Date: Mon, 11 Jan 2010 01:11:52 -0500 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] the LONGINT proposal > > Tony: > > Sorry, I have been too long-winded here. To answer your questions succinctly: > > 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. > > 2. I think checked assignability gets us onto the slippery slope (see below). Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. > > Read on for the long-winded version? > > According to NELSON (SPwM3), ORD and VAL convert between enumerations and INTEGERs, and INTEGER is all integers represented by the implementation. So, the range of INTEGER is likely different for 8-bit, 16-bit, 32-bit, and 64-bit processors. > > Today we see 32-bit and 64-bit processors as predominant, but I remember the day when 8-bit and 16-bit were the norm. Someday we may see 128-bit processors as the norm. > > (I?ve been cleaning up my basement office and ran across a box of 8-inch floppy disks. When I showed them to my daughter she understood the meaning of ?floppy? as opposed to the rigid 3.5-inch floppies of today. But, I digress.) > > On a 64-bit processor, this whole idea of LONGINT as 64-bits then becomes mute since INTEGER will be 64 bits also. But on a 16-bit machine (assuming we had an implementation for one) the native word size would be less than the 32-bits we seem to take for granted now. > > One problem is that one doesn?t really know the range of LONGINT unless we define it as some number of bits. Rodney?s proposal simply stated that LONGINT was at least as big as INTEGER but could be larger. So, on a 64-bit machine, are LONGINT and INTEGER really the same in terms of implementation?, whereas on a 32-bit the LONGINT would have an additional 32-bits more than INTEGER? What about a 128-bit machine? > > I say all this to point out the obvious, namely that LONGINT and INTEGER are different types. > > Therefore, IMO the language must make it clear how these different types interact. > > I would argue that > x: LONGINT := 23; > is wrong! The programmer should have to write > x: LONGINT := 23L; > instead. > > A subrange of LONGINT would be written as [23L..4200L] and would be a different type than the integer subrange [23..4200] even though the ranges are identical. > > Likewise, IMO mixed arithmetic with the compiler deciding what to do is wrong. The programmer should have to explicitly write conversions to a common type for arithmetic. > > I have no problem with extending the existing operators to deal with LONGINT; it?s just that the result should be LONGINT. > Given x: LONGINT := 49L; > INC(x) yields 50L > INC(x, 3L) yields 52L > note that INC(x, 3) would be a syntax error since 3 is an INTEGER and x is a LONGINT > (x + 20L) yields 69L > note that (x + 20) would be a syntax error since 20 is an INTEGER and x is a LONGINT > LAST(LONGINT) yields a LONGINT > > Now that I think about it more, I have a problem using ORD/VAL for the conversion since NELSON defines these as converting between enumerations and INTEGERs, and since LONGINT is a different type than INTEGER and quite possibly has a greater range than INTEGER. Is the proposal to also allow enumerations to use the range of LONGINT ? Enumerations currently are defined as having a range no greater than INTEGER. To extend them to LONGINT would lose the obvious performance benefits of keeping them same range as native INTEGER. > > Maybe we should invent new names for the conversions between INTEGER and LONGINT. Perhaps PROMOTE and DEMOTE or some such. These are probably bad names, but I use them below simply to illustrate (feel free to come up with better names): > Given longInt: LONGINT; and int: INTEGER; > int := DEMOTE(longInt); would perform the conversion from LONGINT to INTEGER and would give a runtime range check error if longInt is too big/small to fit in an INTEGER. > longInt := PROMOTE(int) would always succeed in performing the conversion from INTEGER to LONGINT but would make the conversion explicit > int + DEMOTE(longInt) would yield an INTEGER result with all arithmetic being done in the range of INTEGER > longInt + PROMOTE(int) would yield a LONGINT result with all arithmetic being done in the range of LONGINT > > Now if we were to allow checked assignability (as Tony is leaning toward), I think we begin to get on the slippery slope. How far do we extend this to the point that it is not clear in the expression of the code what is happening? If I can write ?int := longInt;? why not ?int := 23L;? and why not ?int := longInt + 57;? and is this different than ?int := longInt + 57L;?? etc. etc. > > I agree the ORD/VAL syntax is ugly, so that is another reason (besides them applying to enumerations only) we should use different names for the INTEGER/LONGINT conversions. > > Sorry, I have been too long-winded here. To answer your questions succinctly: > > 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. > > 2. I think checked assignability gets us onto the slippery slope. Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. > > Regards, > Randy Coleburn > > From: Tony Hosking [mailto:hosking at cs.purdue.edu] > Sent: Sunday, January 10, 2010 3:43 PM > To: Randy Coleburn > Cc: m3devel > Subject: Re: [M3devel] the LONGINT proposal > > Hi Randy, > > As someone who has actually written Modula-3 programs for a living your opinions are always highly valued. I agree with you in principle and aims, except for requiring overflow to be a checked run-time error. The language definition already has a mechanism for handling this in the require FloatMode interface. It is not something that the compiler should be involved in. I also just now raised a question about perhaps having integer literals adapt their type to the context in which they are used. > > I should point out that the current mainline implementation does exactly what you propose (except overflow checking). It captures the fundamental spirit of Rodney's proposal but does not permit mixed arithmetic or assignment. Can I ask what your issue is w.r.to checked assignability? I am still leaning in favor. It is not much different from assignment from an INTEGER to a subrange, which requires no explicit check, though of course there is a run-time range check. Having programmers explicitly write: > > x: INTEGER := ORD(longint, INTEGER); > > seems unnecessary when they could just write > > x: INTEGER := longint; > > This is similar in spirit to: > > x: [lo..hi] := integer; > > > On 10 Jan 2010, at 15:00, Randy Coleburn wrote: > > > I've been trying to follow along on this topic. > > Here are my thoughts: > > 1. LONGINT should be a distinct type different from INTEGER. > > 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. > > 3. Overflow should be a checked run-time error, not silently wrapped around. > > 4. WRT assignability, I think explicit conversions should be used. > > These statements may make me unpopular with some who don't like to type much, but I've always hated the tradeoff of understandability for brevity in expression. > > The important thing is not how fast we can type up a program, it is rather how hard is it to make a mistake. I think the spirit of Modula-3 is that the language makes you a better programmer by forcing you to make your intentions explicit rather than relying on the compiler to infer your intentions. We need correct and maintainable software, especially at the systems level. Whatever is decided about LONGINT, we need to keep to the original design tenants of the language. > > And yes, I do think we need a LONGINT type, not just to deal with large file sizes. > > But even for long-lived readers/writers, whatever type you choose for the index will eventually be insufficient, so you have to code for the possibility that the range of the long lived reader/writer exceeds the range of your index type. That is just good programming. > > I think sometimes that the new generation of programmers has been warped by what I call the "Microsoft Mentality" where you must expect that you need to reboot/restart every so often to maintain proper performance. Programs should be written to run forever or until their job is completed or they are commanded to stop. > > As "we" begin to converge on the design changes, I like having something concrete to look at, ala Rodney's proposal. Can we take that and keep tweaking it in these emails until we reach a final version acceptable to all? To me this keeps the discussion focused rather than the many different emails. Thus, what I am trying to say is put forth a numbered proposal and each subsequent email must show adjustment to that proposal rather than just a bunch of emails discussing various aspects. Perhaps we should vote on each proposed change, then decide to call a final vote on the whole thing. Who should be involved in such votes? Right now the main persons on the thread are Tony, Jay, Rodney, Mika, Hendrik, Olaf, John, and me. > > My two cents. > > Regards, > Randy Coleburn > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Mon Jan 11 18:42:34 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 12:42:34 -0500 Subject: [M3devel] the LONGINT proposal In-Reply-To: <20100111162301.GA23072@topoi.pooq.com> References: <20100111162301.GA23072@topoi.pooq.com> Message-ID: <06DE4262-4D34-4908-9367-C277E1556416@cs.purdue.edu> We have Word.T and Long.T to handle masking the higher-order bits. On 11 Jan 2010, at 11:23, hendrik at topoi.pooq.com wrote: > On Mon, Jan 11, 2010 at 12:14:06PM +0000, Jay K wrote: >> >> There is some disagreement floating around apparently on even what >> to call the INTEGER <=> LONGINT conversions. >> Currently ORD converts to INTEGER. >> Randy's proposal I believe converts to the underlying type: INTEGER or LONGINT. >> And I think uses VAL(expr, INTEGER or LONGINT) to convert to INTEGER or LONGINT. >> >> >> I believe I saw a proposal that the converesions be named after the type: >> INTEGER(expr), LONGINT(expr). >> >> That kind of smacks to me of "too hard to search for". >> >> Here is a crazy verbose suggestion: >> LOOPHOLE(integer or subrange or enumeration or longint, INTEGER or LONGINT) >> >> and allow it in safe modules? >> At least it is existing syntax with roughly the desired meaning, >> except that LOOPHOLE is and sounds unsafe. >> >> CAST(expr, type) >> CONVERT(expr, type) >> ? >> >> I'm just making up words here of course. >> VAL or ORD seem sufficient, esp. if you can specify the type. > > NARROW? WIDEN? > > And TRUNCATE if you really want to chop off the high-order bits without > overflow check? > > -- hendrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Mon Jan 11 19:39:21 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 13:39:21 -0500 Subject: [M3devel] some more "crazy" proposals In-Reply-To: References: Message-ID: <69F1DBED-115F-44A5-93D6-7C2375EC3E8E@cs.purdue.edu> Jay, as you'll note from the commit messages, I've made ORD/VAL consistent with Rodney's proposal. I think this is much more consistent, in treating VAL as the only *conversion* operator for ordinals. ORD is really just there to allow conversion of enumerations to INTEGER, but for consistency it makes sense to have ORD return the underlying value without any conversion. This makes the equality: ORD(n) = VAL(ORD(n), T) = n where T is the type of n. Unfortunately, it also means that your uses of ORD in the Rd/Wr code must now turn into VAL(n, INTEGER). On 11 Jan 2010, at 07:17, Jay K wrote: > 1) change file/rd/wr sizes to be BigInteger.T > > and/or > > 2) Introduce SeekL, IndexL, StatusL, etc. > default implementation calls Seek/Index/Status and does checked truncation. > Clients gradually port to LONGINT or BigInteger.T. > Completely source compatible. > > > 3) BigInteger.T is The multiple-INTEGER precision type?? > No compiler/language change?? > > > I might try these out, and then go the extra step and port the file dialog to avoid the exception.. > see what it all looks like... > > - Jay From rodney_bates at lcwb.coop Tue Jan 12 01:18:46 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Mon, 11 Jan 2010 18:18:46 -0600 Subject: [M3devel] Mixed arithmetic Message-ID: <4B4BBFE6.1090701@lcwb.coop> Well, I have been mistaken. I finally found the statement about argument types of builtin operators. Every time I go looking for this, I have trouble finding it. I had remembered it wrongly. It does not say an actual argument must be assignable to the type in the signature, it says it must be a _subtype_ of the type in the signature. Actually, it says the overloading is resolved using the subtype relation, but this has the same effect on what is and isn't statically legal. (2.6.1): The particular operation will be selected so that each actual argument type is a subtype of the corresponding formal type or a member of the formal type class. So mixed INTEGER/LONGINT arithmetic does _not_ fall out of the existing rules. We would have to insert 4 different overloaded signatures for +, etc. to allow the mixed arithmetic. Either way, it makes specifying the language changes for LONGINT a lot simpler. This weakens my support of mixed arithmetic. However, there is still some messiness to be resolved. The relations do use assignability rather than subtyping, in such a way that mixed comparisons do fall out of the existing rules. (The overload resolution is done on type class, not type, and doesn't, by itself, preclude mixed INTEGER/ LONGINT comparisons.) Then there are a lot of other places that use assignability. They are: - assignment statements - passing parameters to VALUE or READONLY formals - passing VAR open array parameters (a different kind of assignability, not really relevant) - RAISE statements - RETURN statements - Initial value assignment in a VAR declaration - array subscripts in designators a[i] - elements of set, array, and record constructors - relational operators, including IN - ISTYPE and NARROW (reference types only, thus irrelevant to INTEGER/LONGINT) I too am generally a fan of syntactic explicitness, rather than having things happen behind the scenes, without the programmer's coding them. But if we disallow mixed arithmetic operations, it seems to me that it becomes quite arbitrary where we are allowing assignability and where we are requiring explicit type conversions. Without LONGINT in the picture, this arbitrariness didn't happen, because there was no case where assignability vs. subtyping for the arguments of the arithmetic operators made any difference. I do think it would be particularly inconsistent to disallow the mixed arithmetic but allow mixed relations. As Tony has pointed out, these two differ from the other uses of assignability in having two expressions whose types must be used to infer a common value range to do the operation in. All the other uses of assignability have only one "target" type to assign to. From rodney_bates at lcwb.coop Tue Jan 12 01:25:37 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Mon, 11 Jan 2010 18:25:37 -0600 Subject: [M3devel] Integer overflow In-Reply-To: <3F29FE3F-617D-493E-B687-C53B9D30D6C3@cs.purdue.edu> References: <2A81ABBC-A070-4857-86CF-AA16C7D4AE15@cs.purdue.edu> <3F29FE3F-617D-493E-B687-C53B9D30D6C3@cs.purdue.edu> Message-ID: <4B4BC181.8020807@lcwb.coop> If the type were INTEGER instead of cardinal, (and assuming no checking for overflows), I think wrapping around to the maximal negative value would be reasonable. Even for CARDINAL, it's reasonable for the arithmetic operation itself (which is really being done in the full INTEGER range). But then the assignment of the result back to the CARDINAL variable really must do a range check. This derives from the assignment x:= ... in the WITH equivalent, not from the + 1 operation. Mainly, there is a pervasive principle in the safety of the language that you can never get a bit pattern stored in a variable that does not map back to an abstract value of its type. We really need to preserve this. Tony Hosking wrote: > Even under the interpretation for INC that yields: > > VAR s: CARDINAL := LAST(INTEGER); > BEGIN WITH x = s DO x := VAL(ORD(x) + 1, CARDINAL) END; END; > > the compiler currently does not insert a bounds check, because it reasons that the bound for ORD(x) + 1 is [0+1, LAST(INTEGER)], so the result is always assignable to CARDINAL. > > In reality, the compiler should presumably assume that because ORD(x) + 1 might overflow if ORD(x) = LAST(INTEGER) then the bound for the expression ORD(x)+1 is actually the same as INTEGER: [FIRST(INTEGER),LAST(INTEGER)]. So, because this is larger than the range for CARDINAL it really needs to insert a bounds check on the conversion to CARDINAL. > > On 9 Jan 2010, at 23:33, Tony Hosking wrote: > >> So, in my experiments with range checking on integers, I have been playing with the overflow case: >> >> VAR s: CARDINAL := LAST(INTEGER); >> BEGIN INC(s) END; >> >> Should this fail at runtime with a range check error? >> >> The language definition says that integer overflow may or may not be checked, depending on the implementation. (See FloatMode.i3). >> >> If it is not checked, is it reasonable that s takes on the value FIRST(INTEGER)? >> >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 >> >> >> >> > > From rodney_bates at lcwb.coop Tue Jan 12 01:45:27 2010 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Mon, 11 Jan 2010 18:45:27 -0600 Subject: [M3devel] Integer literals In-Reply-To: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu> References: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu> Message-ID: <4B4BC627.6030103@lcwb.coop> Tony Hosking wrote: > One thing I've really struggled with over the introduction of LONGINT is > the need for distinct literal forms. This strikes me as odd, since > literals are really just ways of writing values, rather than stating > anything about how they should be represented. > (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, > but they really do have incompatible value representations). I agree, the need for distinctly typed literals is much greater for the floating types than the integer types, because they can't be viewed as having overlapping value sets in any reasonable way. > > It strikes me that with checked assignability for INTEGER/LONGINT we > could also potentially treat integer literals as essentially "untyped" > (neither INTEGER nor LONGINT). (I still strongly resist going the route > of having mixed type operands for arithmetic...) > > Here's how things would work with subrange types. > > A subrange written as currently > > [lo .. hi] > > would by default be assumed to have base type INTEGER. The constants > lo/hi must both be in range for INTEGER. > > A subrange with base type LONGINT would be written explicitly: > > [lo .. hi] OF LONGINT > > The constants lo/hi must both be in range for LONGINT. > > We could also support the form: > > [lo .. hi] OF INTEGER > > just for consistency though the "OF INTEGER" qualification would be > unnecessarily verbose. > > Here we are allowing the programmer to state explicitly what the base > type of the subrange should be. This would eliminate _one_ reason for needing distinct integer literals. > > Literals would be be range-checked when used as arithmetic operands or > in assignment, with compile-time checks that they are in range > ("compatible") with the types of the other operands or the destination > of the assignment. The reason I proposed the distinct literals is because of feeling very badly burned by Ada. It has a type "universal integer", which is builtin, and all integer literals have this type. They have unbounded range and a complete set of arithmetic operators, which can only be evaluated at compile time. The type "universal integer" can't be named in source code. The rules for when they are converted to a type having a runtime representation are complicated, messy, highly surprising, and a huge complication of the language. Static type information can propagate a long way through language constructs. The programmer's dilemma in figuring out just what is happening is much worse than arithmetic operators that accept mixed sizes and do the computation in the larger size. Maybe the semantics of this idea could be done better than in Ada, but I spent a lot of time trying, and didn't come up with anything that wasn't both too complicated and not worth the gain, IMO. We should come up with a complete language proposal before going this way. > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > From hosking at cs.purdue.edu Tue Jan 12 02:02:01 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 20:02:01 -0500 Subject: [M3devel] Mixed arithmetic In-Reply-To: <4B4BBFE6.1090701@lcwb.coop> References: <4B4BBFE6.1090701@lcwb.coop> Message-ID: My firm position now is that we continue to disallow both mixed arithmetic *and* assignability, and stick with the status quo as described at: http://www.cs.purdue.edu/~hosking/m3/reference/index.html http://www.cs.purdue.edu/homes/hosking/m3/reference/complete/m3-defn-complete.pdf On 11 Jan 2010, at 19:18, Rodney M. Bates wrote: > Well, I have been mistaken. I finally found the statement about argument > types of builtin operators. Every time I go looking for this, I have trouble > finding it. I had remembered it wrongly. It does not say an actual argument must > be assignable to the type in the signature, it says it must be a _subtype_ > of the type in the signature. Actually, it says the overloading is resolved > using the subtype relation, but this has the same effect on what is and > isn't statically legal. > > (2.6.1): The particular operation will be selected so that each actual > argument type is a subtype of the corresponding formal type or > a member of the formal type class. > > So mixed INTEGER/LONGINT arithmetic does _not_ fall out of the existing > rules. We would have to insert 4 different overloaded signatures for > +, etc. to allow the mixed arithmetic. Either way, it makes specifying the > language changes for LONGINT a lot simpler. > > This weakens my support of mixed arithmetic. > > However, there is still some messiness to be resolved. The relations do use > assignability rather than subtyping, in such a way that mixed comparisons > do fall out of the existing rules. (The overload resolution is done on > type class, not type, and doesn't, by itself, preclude mixed INTEGER/ > LONGINT comparisons.) Then there are a lot of other places > that use assignability. They are: > > - assignment statements > - passing parameters to VALUE or READONLY formals > - passing VAR open array parameters (a different kind of assignability, not > really relevant) > - RAISE statements > - RETURN statements > - Initial value assignment in a VAR declaration > - array subscripts in designators a[i] > - elements of set, array, and record constructors > - relational operators, including IN > - ISTYPE and NARROW (reference types only, thus irrelevant to INTEGER/LONGINT) > > I too am generally a fan of syntactic explicitness, rather than having things > happen behind the scenes, without the programmer's coding them. But if we > disallow mixed arithmetic operations, it seems to me that it becomes > quite arbitrary where we are allowing assignability and where we are > requiring explicit type conversions. > > Without LONGINT in the picture, this arbitrariness didn't happen, because > there was no case where assignability vs. subtyping for the arguments of > the arithmetic operators made any difference. > > I do think it would be particularly inconsistent to disallow the mixed > arithmetic but allow mixed relations. As Tony has pointed out, these > two differ from the other uses of assignability in having two expressions > whose types must be used to infer a common value range to do the operation > in. All the other uses of assignability have only one "target" type to > assign to. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Jan 12 02:18:26 2010 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Jan 2010 01:18:26 +0000 Subject: [M3devel] Integer literals In-Reply-To: <4B4BC627.6030103@lcwb.coop> References: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu>, <4B4BC627.6030103@lcwb.coop> Message-ID: >> One thing I've really struggled with over the introduction of LONGINT is >> the need for distinct literal forms. This strikes me as odd, since >> literals are really just ways of writing values, rather than stating >> anything about how they should be represented. >> (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, >> but they really do have incompatible value representations). > > I agree, the need for distinctly typed literals is much greater for the > floating types than the integer types, because they can't be viewed > as having overlapping value sets in any reasonable way. Huh? This seems to me to be directly opposite of the truth. LONGREAL is a strict superset of REAL in what it can represent. There is *complete* overlap. Am I really mistaken here? Floating point is indeed very wierd, but it isn't this wierd. Right? - Jay ---------------------------------------- From jay.krell at cornell.edu Tue Jan 12 02:21:34 2010 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Jan 2010 01:21:34 +0000 Subject: [M3devel] Mixed arithmetic In-Reply-To: <4B4BBFE6.1090701@lcwb.coop> References: <4B4BBFE6.1090701@lcwb.coop> Message-ID: > rather than having things > happen behind the scenes, without the programmer's coding them Just a reminder that things happen behind the scenes *all the time*. It is the norm, not the exception. Look at what "try" does. It is two or three function calls. Look at the garbage collector. Look at layering in various places. The system is not simple. This isn't a bad thing necessarily. Getting things done often requires complexity. I haven't finished listening to "growing a language" but Steele makes the point that if your language is too small, it is very limiting in what you can elegantly do or do at all. Promoting an INTEGER to a LONGINT is among the simplest things you can do probably. It is simpler in fact than adding 1 to an integer, because it cannot fail, whereas adding 1 can. - Jay From hosking at cs.purdue.edu Tue Jan 12 03:11:23 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 21:11:23 -0500 Subject: [M3devel] Integer literals In-Reply-To: <4B4BC627.6030103@lcwb.coop> References: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu> <4B4BC627.6030103@lcwb.coop> Message-ID: <4405421D-C606-4DC4-B6D4-4C50DA03992B@cs.purdue.edu> Yes, I agree. I am now convinced that relaxing the current spec to allow assignability and mixed operand arithmetic is a swamp that we should steer well clear of. On 11 Jan 2010, at 19:45, Rodney M. Bates wrote: > > > Tony Hosking wrote: >> One thing I've really struggled with over the introduction of LONGINT is the need for distinct literal forms. This strikes me as odd, since literals are really just ways of writing values, rather than stating anything about how they should be represented. >> (Yes, I know that the REAL/LONGREAL/EXTENDED literals are all distinct, but they really do have incompatible value representations). > > I agree, the need for distinctly typed literals is much greater for the > floating types than the integer types, because they can't be viewed > as having overlapping value sets in any reasonable way. > >> It strikes me that with checked assignability for INTEGER/LONGINT we could also potentially treat integer literals as essentially "untyped" (neither INTEGER nor LONGINT). (I still strongly resist going the route of having mixed type operands for arithmetic...) >> Here's how things would work with subrange types. >> A subrange written as currently >> [lo .. hi] >> would by default be assumed to have base type INTEGER. The constants lo/hi must both be in range for INTEGER. >> A subrange with base type LONGINT would be written explicitly: >> [lo .. hi] OF LONGINT >> The constants lo/hi must both be in range for LONGINT. >> We could also support the form: >> [lo .. hi] OF INTEGER >> just for consistency though the "OF INTEGER" qualification would be unnecessarily verbose. >> Here we are allowing the programmer to state explicitly what the base type of the subrange should be. > > This would eliminate _one_ reason for needing distinct integer literals. > >> Literals would be be range-checked when used as arithmetic operands or in assignment, with compile-time checks that they are in range ("compatible") with the types of the other operands or the destination of the assignment. > > The reason I proposed the distinct literals is because of feeling very > badly burned by Ada. It has a type "universal integer", which is builtin, > and all integer literals have this type. They have unbounded range and > a complete set of arithmetic operators, which can only be evaluated at > compile time. The type "universal integer" can't be named in source > code. > > The rules for when they are converted to a type having a runtime representation > are complicated, messy, highly surprising, and a huge complication of the > language. Static type information can propagate a long way through > language constructs. The programmer's dilemma in figuring out just what > is happening is much worse than arithmetic operators that accept mixed > sizes and do the computation in the larger size. > > Maybe the semantics of this idea could be done better than in Ada, but I spent > a lot of time trying, and didn't come up with anything that wasn't both too > complicated and not worth the gain, IMO. > > We should come up with a complete language proposal before going this way. > > > >> Antony Hosking | Associate Professor | Computer Science | Purdue University >> 305 N. University Street | West Lafayette | IN 47907 | USA >> Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Jan 12 03:09:39 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 21:09:39 -0500 Subject: [M3devel] Integer overflow In-Reply-To: <4B4BC181.8020807@lcwb.coop> References: <2A81ABBC-A070-4857-86CF-AA16C7D4AE15@cs.purdue.edu> <3F29FE3F-617D-493E-B687-C53B9D30D6C3@cs.purdue.edu> <4B4BC181.8020807@lcwb.coop> Message-ID: <8432422C-A96C-4A0A-A8F9-9EC10963548A@cs.purdue.edu> If the type were INTEGER instead of CARDINAL then the current implementation *does* allow wrap-around. I've fixed the range check so that overflow does not permit the bits for FIRST(INTEGER) to be stored in the CARDINAL. On 11 Jan 2010, at 19:25, Rodney M. Bates wrote: > If the type were INTEGER instead of cardinal, (and assuming no checking for overflows), > I think wrapping around to the maximal negative value would be reasonable. Even for > CARDINAL, it's reasonable for the arithmetic operation itself (which is really being > done in the full INTEGER range). But then the assignment of the result back to the > CARDINAL variable really must do a range check. This derives from the assignment > x:= ... in the WITH equivalent, not from the + 1 operation. > > Mainly, there is a pervasive principle in the safety of the language that you can > never get a bit pattern stored in a variable that does not map back to an abstract > value of its type. We really need to preserve this. > > Tony Hosking wrote: >> Even under the interpretation for INC that yields: >> VAR s: CARDINAL := LAST(INTEGER); >> BEGIN WITH x = s DO x := VAL(ORD(x) + 1, CARDINAL) END; END; >> the compiler currently does not insert a bounds check, because it reasons that the bound for ORD(x) + 1 is [0+1, LAST(INTEGER)], so the result is always assignable to CARDINAL. >> In reality, the compiler should presumably assume that because ORD(x) + 1 might overflow if ORD(x) = LAST(INTEGER) then the bound for the expression ORD(x)+1 is actually the same as INTEGER: [FIRST(INTEGER),LAST(INTEGER)]. So, because this is larger than the range for CARDINAL it really needs to insert a bounds check on the conversion to CARDINAL. >> On 9 Jan 2010, at 23:33, Tony Hosking wrote: >>> So, in my experiments with range checking on integers, I have been playing with the overflow case: >>> >>> VAR s: CARDINAL := LAST(INTEGER); >>> BEGIN INC(s) END; >>> >>> Should this fail at runtime with a range check error? >>> >>> The language definition says that integer overflow may or may not be checked, depending on the implementation. (See FloatMode.i3). >>> >>> If it is not checked, is it reasonable that s takes on the value FIRST(INTEGER)? >>> >>> Antony Hosking | Associate Professor | Computer Science | Purdue University >>> 305 N. University Street | West Lafayette | IN 47907 | USA >>> Office +1 765 494 6001 | Mobile +1 765 427 5484 >>> >>> >>> >>> -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Jan 12 03:18:00 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 21:18:00 -0500 Subject: [M3devel] Mixed arithmetic In-Reply-To: References: <4B4BBFE6.1090701@lcwb.coop> Message-ID: <69ECEB1D-AAE2-4C98-8BEE-7F06824C8485@cs.purdue.edu> On 11 Jan 2010, at 20:21, Jay K wrote: > >> rather than having things >> happen behind the scenes, without the programmer's coding them > > > Just a reminder that things happen behind the scenes *all the time*. > It is the norm, not the exception. > Look at what "try" does. > It is two or three function calls. Conceptually it need not be. Moreover, the effects are not something the programmer needs to reason about. > Look at the garbage collector. Again, that is not visible to the programmer. Same again re programmer reasoning. > Look at layering in various places. > The system is not simple. > This isn't a bad thing necessarily. > Getting things done often requires complexity. > I haven't finished listening to "growing a language" but Steele makes the point that if your language is too small, it is very limiting in what you can elegantly do or do at all. His conclusion is interesting, and reflects the decision to grow Java not by language extension but by library extension. > Promoting an INTEGER to a LONGINT is among the simplest things you can do probably. > > > It is simpler in fact than adding 1 to an integer, because it cannot fail, whereas adding 1 can. Let's enumerate some complexity. What does LAST(INTEGER) + 1 mean? What about LAST(INTEGER) + 1L? Why should they mean something different? Let's assume that it's all just values. Then we want the same interpretation for both expressions. But we must live in the real world where the meaning of "+" must be implemented using the limited integer range of the machine. I think that the status quo is a reasonable place to be. Yes, it means that you have to write VAL(LAST(INTEGER), LONGINT) + 1L to get something different than LAST(INTEGER)+1, but at least it retains referential transparency. I strongly support the status quo. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Jan 12 04:02:55 2010 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Jan 2010 03:02:55 +0000 Subject: [M3devel] 64bit file sizes now? Message-ID: So.. LONGINT as I understand will remain roughly as it was, except VAL(expr, INTEGER) is how you convert expr to INTEGER, instead of ORD(expr). And this is already in place. ? So I should go ahead and update File.i3/Status/size and Rd/Wr/Index/Seek/Length to all be LONGINT, "whatever the consequences"? The consequences are roughly the first diff I sent out, with the caveats that I used ORD() instead of VAL(,INTEGER), and a few packages were left to fix. It is mechanical and simple and predictable, just tedious and ugly. Most Rd/Wr users are limited to INTEGER "sizes" anyway, but a few might gain capacity. Classic simple example is the mklib and libdump code, they read the entire file into memory and then deal with that. I can send the diffs ahead of time, but there's really no choices left as to what they'll look like, it is forced by the limited capability of LONGINT. Had they used LONGINT in the first place, of course, there'd be no diff at this time, the ugliness would have been builtin from the start. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Jan 12 04:10:06 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 22:10:06 -0500 Subject: [M3devel] 64bit file sizes now? In-Reply-To: References: Message-ID: <185464DB-5CA9-4D5B-BCF7-9F7048D9FA05@cs.purdue.edu> On 11 Jan 2010, at 22:02, Jay K wrote: > So.. LONGINT as I understand will remain roughly as it was, except VAL(expr, INTEGER) is how you convert expr to INTEGER, instead of ORD(expire). That's what I think makes most sense. > And this is already in place. Yes, it's in place. > ? > > So I should go ahead and update File.i3/Status/size and Rd/Wr/Index/Seek/Length to all be LONGINT, "whatever the consequences"? The consequences are roughly the first diff I sent out, with the caveats that I used ORD() instead of VAL(,INTEGER), and a few packages were left to fix. It is mechanical and simple and predictable, just tedious and ugly. > Most Rd/Wr users are limited to INTEGER "sizes" anyway, but a few might gain capacity. > Classic simple example is the mklib and libdump code, they read the entire file into memory and then deal with that. If the use-case is typically INTEGER then perhaps we need to think of alternatives using abstraction? > I can send the diffs ahead of time, but there's really no choices left as to what they'll look like, it is forced by the limited capability of LONGINT. > Had they used LONGINT in the first place, of course, there'd be no diff at this time, the ugliness would have been builtin from the start. When they originally wrote it large file sizes were only proposed not implemented. I don't think C even had long long then. (Yes, I am showing my age! -- we are talking almost 20 years ago now!) If they had used LONGINT from the start then folks would have not had any ugliness because all would have used LONGINT. Now, to save some hassles in future, perhaps we need a better abstraction! Let's ponder that before you propagate your changes. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Jan 12 04:10:52 2010 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Jan 2010 03:10:52 +0000 Subject: [M3devel] Mixed arithmetic In-Reply-To: <69ECEB1D-AAE2-4C98-8BEE-7F06824C8485@cs.purdue.edu> References: <4B4BBFE6.1090701@lcwb.coop>, , <69ECEB1D-AAE2-4C98-8BEE-7F06824C8485@cs.purdue.edu> Message-ID: The limited range of efficient integers will always be a problem. After all, in the real world, there is no such thing as LAST(INTEGER), nor the notion that + can fail, but even in Modula-3 we have both of these unfortunate things for efficiency. It is a wierd system already. Having LAST(INTEGER) + 1 fail or be FIRST(INTEGER) but LAST(INTEGER) + 1L provide a more sensible result I'm skeptical makes it any worse or wierder than it already is. On the other hand, rd/wr/file ugliness is also fairly unavoidable, and just would have been there from the start had things been done right. It is the unavoidable case that "large" files, even if they do fit in address space, are hard to deal with efficiently. Programmers are very used to efficient random access and often don't design for sequential access. And heck, with the rise of SSDs replacing spinning magnetic disks, it isn't going to matter any longer anyway. - Jay From: hosking at cs.purdue.edu Date: Mon, 11 Jan 2010 21:18:00 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] Mixed arithmetic On 11 Jan 2010, at 20:21, Jay K wrote: rather than having things happen behind the scenes, without the programmer's coding them Just a reminder that things happen behind the scenes *all the time*. It is the norm, not the exception. Look at what "try" does. It is two or three function calls. Conceptually it need not be. Moreover, the effects are not something the programmer needs to reason about. Look at the garbage collector. Again, that is not visible to the programmer. Same again re programmer reasoning. Look at layering in various places. The system is not simple. This isn't a bad thing necessarily. Getting things done often requires complexity. I haven't finished listening to "growing a language" but Steele makes the point that if your language is too small, it is very limiting in what you can elegantly do or do at all. His conclusion is interesting, and reflects the decision to grow Java not by language extension but by library extension. Promoting an INTEGER to a LONGINT is among the simplest things you can do probably. It is simpler in fact than adding 1 to an integer, because it cannot fail, whereas adding 1 can. Let's enumerate some complexity. What does LAST(INTEGER) + 1 mean? What about LAST(INTEGER) + 1L? Why should they mean something different? Let's assume that it's all just values. Then we want the same interpretation for both expressions. But we must live in the real world where the meaning of "+" must be implemented using the limited integer range of the machine. I think that the status quo is a reasonable place to be. Yes, it means that you have to write VAL(LAST(INTEGER), LONGINT) + 1L to get something different than LAST(INTEGER)+1, but at least it retains referential transparency. I strongly support the status quo. -------------- next part -------------- An HTML attachment was scrubbed... URL: From rcolebur at SCIRES.COM Tue Jan 12 04:11:51 2010 From: rcolebur at SCIRES.COM (Randy Coleburn) Date: Mon, 11 Jan 2010 22:11:51 -0500 Subject: [M3devel] the LONGINT proposal In-Reply-To: <2158B017-4405-40B6-A750-FAD2BAA88BCB@cs.purdue.edu> References: <20100110051218.2F3C42474001@birch.elegosoft.com> <73D2F123-F308-4210-9655-1F80F9A5C370@cs.purdue.edu> <2158B017-4405-40B6-A750-FAD2BAA88BCB@cs.purdue.edu> Message-ID: Tony et al: Yes, I think I am supporting the "status quo", which seems to be Rodney's proposal, minus mixed arithmetic and checked assignability; plus my discomfort with ORD/VAL as you state. (See discussion below to the end for more on this "discomfort" and the problem I see with converting from LONGINT to INTEGER.) When I said we don't know the range of LONGINT, I meant that in the context of documenting the language we weren't specifying this range; rather it is implementation-defined. Indeed, yes you must be able to do FIRST(LONGINT) and LAST(LONGINT) at runtime to determine the actual range. Tony you stated in your response that the 2nd parameter (the type) of VAL is optional. I was not aware that this parameter can be defaulted. Where is this stated in the language spec? I've only scanned your HTML reference briefly, but it seems to me that even there it still says that ORD/VAL convert between enumerations and INTEGERs, not LONGINTs. Are we going to allow LONGINT to be an enumeration? If so, then why not go full bore and just make INTEGER a subrange of LONGINT? (I don't favor this.) Alternately, if you want to use ORD/VAL for the LONGINT conversions, could we at least change 2.2.1 to say that ORD/VAL convert between ordinal types, since enumerations are defined as an ordinal type and LONGINT falls into the category of an ordinal type, but not an enumeration type? Indeed, the syntax definition of ORD/VAL seem to bear out this fact even though the text references "enumerations" (see 4th major paragraph in 2.2.1, "The operators ORD and VAL convert between ..."). The syntax of ORD/VAL is: ORD (element: Ordinal): Integer VAL (i: Integer; T: OrdinalType): T and, if n is a integer of type T, ORD(n) = VAL(n, T) = n. BTW: I think the above identity should say that n is a non-negative integer! So, using these, you propose one would write longInt := VAL(int, LONGINT); int := ORD(longInt) then, the identity doesn't exactly match up unless you allow ORD(longInt) to return a LONGINT, but then if you do that the signature of ORD must be dependent on its argument type (either INTEGER or LONGINT; note that enumerations and INTEGER subranges also yield type INTEGER). Therefore, in the case of argument LONGINT, the type of the LHS of ORD must be a LONGINT; and the LHS type must be INTEGER when the argument is INTEGER, unless you allow checked assignability, in which case why do you need ORD in the first place? IMO, ORD/VAL make more sense in the case of enumerations. For example: Color = (Red, Blue, Green); ORD(Color.Blue) = 1 VAL(1, Color) = Color.Blue (Note that the identity doesn't apply here since n isn't an integer when applied to ORD, or to the result of VAL.) I think I saw later in one of the commit messages or replies to Jay that you propose to drop use of ORD with LONGINT and just use VAL, as in: longInt := VAL(int, LONGINT); int := VAL(longInt, INTEGER); but the second form would violate the signature of VAL, which requires an INTEGER as the first argument. I guess my heartburn with using ORD/VAL for LONGINT conversions stems from fact that before LONGINT, enumerations, subranges, and INTEGER all had the same maximum range and NELSON states that ORD/VAL are for conversions between enumerations (aka ordinals) and integers. Note that NELSON uses lowercase "integers" (should really be "non-negative integers") so I guess this could mean all non-negative integers, whether representable as INTEGER or LONGINT, but then there was no LONGINT when NELSON's book came out. Also, before LONGINT, ORD could not cause a checked runtime error. So, at this point, to summarize, I think you are advocating: 1. Distinct types INTEGER and LONGINT. 2. LONGINT is an ordinal type, but cannot be used as the index type for an array. 3. Enumerations are still constrained to no more than NUMBER(CARDINAL) total values, i.e., (LAST(INTEGER)+1). 4. No mixed arithmetic between INTEGER and LONGINT; require explicit conversions. 5. No mixed comparisons between INTEGER and LONGINT; require explicit conversions. 6. Allow VAL to convert INTEGER to LONGINT. Am I correct so far? Now, what to do about converting from LONGINT to INTEGER? a. Originally, ORD was proposed along with use of a checked runtime error if the value of the LONGINT didn't fit into an INTEGER. But, then the result type signature of ORD (i.e., INTEGER) doesn't preserve the identity ORD(n) = VAL(n, T) = n when T is LONGINT. To allow this, you would have to make the result type of ORD dependent on the parameter type passed to ORD. b. Provide an overloaded form of VAL with a different signature that allows for int := VAL(longInt, INTEGER). I think this is somewhat confusing in terms of the original definition of VAL as an inverse of ORD. c. Allow for checked assignability, e.g., int := longInt; but then this to me starts us on the slippery slope where one eventually argues for mixed arithmetic. d. Come up with differently named operators (different from ORD/VAL). These would have the benefit of requiring only one parameter, whereas VAL requires two, and would prevent any confusion with the defined use of ORD/VAL as conversion inverses for enumerations and integers. This is my preferred option. e. Any other ideas? Regards, Randy From: Tony Hosking [mailto:hosking at cs.purdue.edu] Sent: Monday, January 11, 2010 12:32 PM To: Randy Coleburn Cc: m3devel Subject: Re: [M3devel] the LONGINT proposal Quick summary: I agree, and you seem to be supporting the status quo (other than your discomfort with ORD/VAL) as defined at: http://www.cs.purdue.edu/homes/hosking/m3/reference/ On 11 Jan 2010, at 01:11, Randy Coleburn wrote: Tony: Sorry, I have been too long-winded here. To answer your questions succinctly: 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. Agreed. 2. I think checked assignability gets us onto the slippery slope (see below). Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. Read on for the long-winded version... According to NELSON (SPwM3), ORD and VAL convert between enumerations and INTEGERs, and INTEGER is all integers represented by the implementation. So, the range of INTEGER is likely different for 8-bit, 16-bit, 32-bit, and 64-bit processors. Today we see 32-bit and 64-bit processors as predominant, but I remember the day when 8-bit and 16-bit were the norm. Someday we may see 128-bit processors as the norm. (I've been cleaning up my basement office and ran across a box of 8-inch floppy disks. When I showed them to my daughter she understood the meaning of "floppy" as opposed to the rigid 3.5-inch floppies of today. But, I digress.) On a 64-bit processor, this whole idea of LONGINT as 64-bits then becomes mute since INTEGER will be 64 bits also. But on a 16-bit machine (assuming we had an implementation for one) the native word size would be less than the 32-bits we seem to take for granted now. One problem is that one doesn't really know the range of LONGINT unless we define it as some number of bits. Rodney's proposal simply stated that LONGINT was at least as big as INTEGER but could be larger. So, on a 64-bit machine, are LONGINT and INTEGER really the same in terms of implementation?, whereas on a 32-bit the LONGINT would have an additional 32-bits more than INTEGER? What about a 128-bit machine? What's wrong with using FIRST(LONGINT) and LAST(LONGINT) to determine the range? This is currently implemented. On a 64-bit machine the types LONGINT and INTEGER are still distinct in the current implementation, so cannot be assigned, though they do happen to have the same underlying representation. I say all this to point out the obvious, namely that LONGINT and INTEGER are different types. Correct. The current implementation treats them as completely separate. Therefore, IMO the language must make it clear how these different types interact. I would argue that x: LONGINT := 23; is wrong! The programmer should have to write x: LONGINT := 23L; instead. This is what we currently implement. A subrange of LONGINT would be written as [23L..4200L] and would be a different type than the integer subrange [23..4200] even though the ranges are identical. Also what we currently implement. Likewise, IMO mixed arithmetic with the compiler deciding what to do is wrong. The programmer should have to explicitly write conversions to a common type for arithmetic. I agree, and this is the current implementation. I have no problem with extending the existing operators to deal with LONGINT; it's just that the result should be LONGINT. Given x: LONGINT := 49L; INC(x) yields 50L INC(x, 3L) yields 52L note that INC(x, 3) would be a syntax error since 3 is an INTEGER and x is a LONGINT (x + 20L) yields 69L note that (x + 20) would be a syntax error since 20 is an INTEGER and x is a LONGINT LAST(LONGINT) yields a LONGINT This is exactly the current implementation. Now that I think about it more, I have a problem using ORD/VAL for the conversion since NELSON defines these as converting between enumerations and INTEGERs, and since LONGINT is a different type than INTEGER and quite possibly has a greater range than INTEGER. Is the proposal to also allow enumerations to use the range of LONGINT ? Enumerations currently are defined as having a range no greater than INTEGER. To extend them to LONGINT would lose the obvious performance benefits of keeping them same range as native INTEGER. I'm not sure that the current implementation conflicts with the definition of ORD/VAL. What we currently permit is ORD(LONGINT) to do a *checked* conversion of a LONGINT to an INTEGER. The optional type parameter of VAL can be LONGINT, which permits conversion of INTEGER to LONGINT. I don't see how these conflict with the intention of ORD/VAL. You can see the language spec for what is currently implemented at: http://www.cs.purdue.edu/~hosking/m3/reference/. Maybe we should invent new names for the conversions between INTEGER and LONGINT. Perhaps PROMOTE and DEMOTE or some such. These are probably bad names, but I use them below simply to illustrate (feel free to come up with better names): Given longInt: LONGINT; and int: INTEGER; int := DEMOTE(longInt); would perform the conversion from LONGINT to INTEGER and would give a runtime range check error if longInt is too big/small to fit in an INTEGER. longInt := PROMOTE(int) would always succeed in performing the conversion from INTEGER to LONGINT but would make the conversion explicit int + DEMOTE(longInt) would yield an INTEGER result with all arithmetic being done in the range of INTEGER longInt + PROMOTE(int) would yield a LONGINT result with all arithmetic being done in the range of LONGINT I think ORD/VAL suffice... Now if we were to allow checked assignability (as Tony is leaning toward), I think we begin to get on the slippery slope. How far do we extend this to the point that it is not clear in the expression of the code what is happening? If I can write "int := longInt;" why not "int := 23L;" and why not "int := longInt + 57;" and is this different than "int := longInt + 57L;"? etc. etc. I agree the ORD/VAL syntax is ugly, so that is another reason (besides them applying to enumerations only) we should use different names for the INTEGER/LONGINT conversions. Sorry, I have been too long-winded here. To answer your questions succinctly: 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. 2. I think checked assignability gets us onto the slippery slope. Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. Regards, Randy Coleburn From: Tony Hosking [mailto:hosking at cs.purdue.edu] Sent: Sunday, January 10, 2010 3:43 PM To: Randy Coleburn Cc: m3devel Subject: Re: [M3devel] the LONGINT proposal Hi Randy, As someone who has actually written Modula-3 programs for a living your opinions are always highly valued. I agree with you in principle and aims, except for requiring overflow to be a checked run-time error. The language definition already has a mechanism for handling this in the require FloatMode interface. It is not something that the compiler should be involved in. I also just now raised a question about perhaps having integer literals adapt their type to the context in which they are used. I should point out that the current mainline implementation does exactly what you propose (except overflow checking). It captures the fundamental spirit of Rodney's proposal but does not permit mixed arithmetic or assignment. Can I ask what your issue is w.r.to checked assignability? I am still leaning in favor. It is not much different from assignment from an INTEGER to a subrange, which requires no explicit check, though of course there is a run-time range check. Having programmers explicitly write: x: INTEGER := ORD(longint, INTEGER); seems unnecessary when they could just write x: INTEGER := longint; This is similar in spirit to: x: [lo..hi] := integer; On 10 Jan 2010, at 15:00, Randy Coleburn wrote: I've been trying to follow along on this topic. Here are my thoughts: 1. LONGINT should be a distinct type different from INTEGER. 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. 3. Overflow should be a checked run-time error, not silently wrapped around. 4. WRT assignability, I think explicit conversions should be used. These statements may make me unpopular with some who don't like to type much, but I've always hated the tradeoff of understandability for brevity in expression. The important thing is not how fast we can type up a program, it is rather how hard is it to make a mistake. I think the spirit of Modula-3 is that the language makes you a better programmer by forcing you to make your intentions explicit rather than relying on the compiler to infer your intentions. We need correct and maintainable software, especially at the systems level. Whatever is decided about LONGINT, we need to keep to the original design tenants of the language. And yes, I do think we need a LONGINT type, not just to deal with large file sizes. But even for long-lived readers/writers, whatever type you choose for the index will eventually be insufficient, so you have to code for the possibility that the range of the long lived reader/writer exceeds the range of your index type. That is just good programming. I think sometimes that the new generation of programmers has been warped by what I call the "Microsoft Mentality" where you must expect that you need to reboot/restart every so often to maintain proper performance. Programs should be written to run forever or until their job is completed or they are commanded to stop. As "we" begin to converge on the design changes, I like having something concrete to look at, ala Rodney's proposal. Can we take that and keep tweaking it in these emails until we reach a final version acceptable to all? To me this keeps the discussion focused rather than the many different emails. Thus, what I am trying to say is put forth a numbered proposal and each subsequent email must show adjustment to that proposal rather than just a bunch of emails discussing various aspects. Perhaps we should vote on each proposed change, then decide to call a final vote on the whole thing. Who should be involved in such votes? Right now the main persons on the thread are Tony, Jay, Rodney, Mika, Hendrik, Olaf, John, and me. My two cents. Regards, Randy Coleburn -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Jan 12 04:16:42 2010 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Jan 2010 03:16:42 +0000 Subject: [M3devel] 64bit file sizes now? In-Reply-To: <185464DB-5CA9-4D5B-BCF7-9F7048D9FA05@cs.purdue.edu> References: , <185464DB-5CA9-4D5B-BCF7-9F7048D9FA05@cs.purdue.edu> Message-ID: Large files (64bit file sizes) are very old. Windows 95 had them in the released API 14+ years ago (1995), NT a few years before that (1993?), betas earlier. I heard VMS had 64bit file sizes but I haven't confirmed. > If the use-case is typically INTEGER then perhaps we > need to think of alternatives using abstraction? Hm. StatusLong, SeekLong, IndexLong, LengthLong? Default calls Seek/Index/Length, range checked truncation? Kind of an annoying duplicity of APIs though. - Jay From: hosking at cs.purdue.edu Date: Mon, 11 Jan 2010 22:10:06 -0500 To: jay.krell at cornell.edu CC: m3devel at elegosoft.com Subject: Re: [M3devel] 64bit file sizes now? On 11 Jan 2010, at 22:02, Jay K wrote: So.. LONGINT as I understand will remain roughly as it was, except VAL(expr, INTEGER) is how you convert expr to INTEGER, instead of ORD(expire). That's what I think makes most sense. And this is already in place. Yes, it's in place. ? So I should go ahead and update File.i3/Status/size and Rd/Wr/Index/Seek/Length to all be LONGINT, "whatever the consequences"? The consequences are roughly the first diff I sent out, with the caveats that I used ORD() instead of VAL(,INTEGER), and a few packages were left to fix. It is mechanical and simple and predictable, just tedious and ugly. Most Rd/Wr users are limited to INTEGER "sizes" anyway, but a few might gain capacity. Classic simple example is the mklib and libdump code, they read the entire file into memory and then deal with that. If the use-case is typically INTEGER then perhaps we need to think of alternatives using abstraction? I can send the diffs ahead of time, but there's really no choices left as to what they'll look like, it is forced by the limited capability of LONGINT. Had they used LONGINT in the first place, of course, there'd be no diff at this time, the ugliness would have been builtin from the start. When they originally wrote it large file sizes were only proposed not implemented. I don't think C even had long long then. (Yes, I am showing my age! -- we are talking almost 20 years ago now!) If they had used LONGINT from the start then folks would have not had any ugliness because all would have used LONGINT. Now, to save some hassles in future, perhaps we need a better abstraction! Let's ponder that before you propagate your changes. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Tue Jan 12 04:27:23 2010 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Tue, 12 Jan 2010 03:27:23 +0000 (GMT) Subject: [M3devel] 64bit file sizes now? In-Reply-To: Message-ID: <420956.32527.qm@web23605.mail.ird.yahoo.com> Hi all: forgive my ignorance of current discussion and implementation of LONGINT but I read something about arithmetic overflow; I didn't feel was reasonable even if the current implementation doesn't support arithmetic overflow checks, I must say we can't assume this expression: (LAST(INTEGER) + 1) = FIRST (INTEGER) This sort expression by itself should be catched at compile or run time as an execution error as any CPU would halt in such a case of division by zero, or at least a flag (an exception, etc). Nonetheless writing code in CM3 that exploit this restriction would be useless in M3 systems with overflow checking, so I really want to say that at least we can't assume M3 code to do this kind of "assumptions". It other words this is unsafe. I don't how far would people like to have checks on arithmetic expressions, what do you think of creating a compiler option to generate arithmetic overflow check code. Please let me know if I'm wrong about this issue on current discussions. --- El lun, 11/1/10, Jay K escribi?: > De: Jay K > Asunto: [M3devel] 64bit file sizes now? > Para: "m3devel" > Fecha: lunes, 11 de enero, 2010 22:02 > > > > > > So.. LONGINT as I understand will remain roughly as it was, > except VAL(expr, INTEGER) is how you convert expr to > INTEGER, instead of ORD(expr). > > > > > > And this is already in place. > > > > > > ? > > > > > > So I should go ahead and update File.i3/Status/size and > Rd/Wr/Index/Seek/Length to all be LONGINT, "whatever > the consequences"? The consequences are roughly the > first diff I sent out, with the caveats that I used ORD() > instead of VAL(,INTEGER), and a few packages were left to > fix. It is mechanical and simple and predictable, just > tedious and ugly. > Most Rd/Wr users are limited to INTEGER "sizes" > anyway, but a few might gain capacity. > > Classic simple example is the mklib and libdump code, they > read the entire file into memory and then deal with that. > > > > > > I can send the diffs ahead of time, but there's really > no choices left as to what they'll look like, it is > forced by the limited capability of LONGINT. > > Had they used LONGINT in the first place, of course, > there'd be no diff at this time, the ugliness would have > been builtin from the start. > > > > > > - Jay > > > From hosking at cs.purdue.edu Tue Jan 12 04:40:28 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 22:40:28 -0500 Subject: [M3devel] the LONGINT proposal In-Reply-To: References: <20100110051218.2F3C42474001@birch.elegosoft.com> <73D2F123-F308-4210-9655-1F80F9A5C370@cs.purdue.edu> <2158B017-4405-40B6-A750-FAD2BAA88BCB@cs.purdue.edu> Message-ID: <26567A2B-DF4C-460C-A06C-3C534731FA53@cs.purdue.edu> On 11 Jan 2010, at 22:11, Randy Coleburn wrote: > Tony et al: > > Yes, I think I am supporting the ?status quo?, which seems to be Rodney?s proposal, minus mixed arithmetic and checked assignability; plus my discomfort with ORD/VAL as you state. (See discussion below to the end for more on this ?discomfort? and the problem I see with converting from LONGINT to INTEGER.) > > When I said we don?t know the range of LONGINT, I meant that in the context of documenting the language we weren?t specifying this range; rather it is implementation-defined. Indeed, yes you must be able to do FIRST(LONGINT) and LAST(LONGINT) at runtime to determine the actual range. > > Tony you stated in your response that the 2nd parameter (the type) of VAL is optional. I was not aware that this parameter can be defaulted. Where is this stated in the language spec? Sorry, my error. I realised after writing that I had mis-spoken. > I?ve only scanned your HTML reference briefly, but it seems to me that even there it still says that ORD/VAL convert between enumerations and INTEGERs, not LONGINTs. That wording is exactly the same as it has always been. Here is the diff from the original specification (before LONGINT): 55,56c55,56 < ORD (element: Ordinal): INTEGER < VAL (i: INTEGER; T: OrdinalType): T --- > ORD (element: Ordinal): Integer > VAL (i: Integer; T: OrdinalType): T 74c74 < If n is an integer, ORD(n) = VAL(n, INTEGER) = n. --- > If n is an integer of type T, ORD(n) = VAL(n, T) = n. Notice that all that I have changed is to allow ORD to return INTEGER or LONGINT, depending on the type of the element. And VAL simply takes an INTEGER or LONGINT and converts to an Ordinal type T. > Are we going to allow LONGINT to be an enumeration? If so, then why not go full bore and just make INTEGER a subrange of LONGINT? (I don?t favor this.) No, enumerations map only onto INTEGER. > Alternately, if you want to use ORD/VAL for the LONGINT conversions, could we at least change 2.2.1 to say that ORD/VAL convert between ordinal types, since enumerations are defined as an ordinal type and LONGINT falls into the category of an ordinal type, but not an enumeration type? Indeed, the syntax definition of ORD/VAL seem to bear out this fact even though the text references ?enumerations? (see 4th major paragraph in 2.2.1, ?The operators ORD and VAL convert between ??). I don't want to make wholesale changes to the reference that were not there in the first place. ORD applied to and INTEGER has always been the identity operation. > The syntax of ORD/VAL is: > ORD (element: Ordinal): Integer > VAL (i: Integer; T: OrdinalType): T > and, if n is a integer of type T, ORD(n) = VAL(n, T) = n. > > BTW: I think the above identity should say that n is a non-negative integer! Huh? No, that is not the case. It is only non-negative for enumerations which count from 0. > So, using these, you propose one would write > longInt := VAL(int, LONGINT); > int := ORD(longInt) No, longint := VAL(integer, LONGINT) integer := VAL(longint, INTEGER) int := ORD(int) longint := ORD(longint) > then, the identity doesn?t exactly match up unless you allow ORD(longInt) to return a LONGINT, but then if you do that the signature of ORD must be dependent on its argument type (either INTEGER or LONGINT; note that enumerations and INTEGER subranges also yield type INTEGER). This captures the identities precisely, which is why I reverted to the original formulation. > Therefore, in the case of argument LONGINT, the type of the LHS of ORD must be a LONGINT; and the LHS type must be INTEGER when the argument is INTEGER, unless you allow checked assignability, in which case why do you need ORD in the first place? > > IMO, ORD/VAL make more sense in the case of enumerations. For example: > Color = (Red, Blue, Green); > ORD(Color.Blue) = 1 > VAL(1, Color) = Color.Blue > (Note that the identity doesn?t apply here since n isn?t an integer when applied to ORD, or to the result of VAL.) Yes, of course, ORD/VAL are there to allow mapping of enumerations to INTEGER. But, for general consistency any integer can have ORD applied to it, and any integer can be mapped to its own type. > I think I saw later in one of the commit messages or replies to Jay that you propose to drop use of ORD with LONGINT and just use VAL, as in: > longInt := VAL(int, LONGINT); > int := VAL(longInt, INTEGER); That is what is now implemented. > but the second form would violate the signature of VAL, which requires an INTEGER as the first argument. No, notice that VAL takes an Integer which can be INTEGER or LONGINT typed. > I guess my heartburn with using ORD/VAL for LONGINT conversions stems from fact that before LONGINT, enumerations, subranges, and INTEGER all had the same maximum range and NELSON states that ORD/VAL are for conversions between enumerations (aka ordinals) and integers. Note that NELSON uses lowercase ?integers? (should really be ?non-negative integers?) so I guess this could mean all non-negative integers, whether representable as INTEGER or LONGINT, but then there was no LONGINT when NELSON?s book came out. Also, before LONGINT, ORD could not cause a checked runtime error. ORD now can never cause a checked runtime error, just as with Nelson. > So, at this point, to summarize, I think you are advocating: > 1. Distinct types INTEGER and LONGINT. > 2. LONGINT is an ordinal type, but cannot be used as the index type for an array. > 3. Enumerations are still constrained to no more than NUMBER(CARDINAL) total values, i.e., (LAST(INTEGER)+1). > 4. No mixed arithmetic between INTEGER and LONGINT; require explicit conversions. > 5. No mixed comparisons between INTEGER and LONGINT; require explicit conversions. > 6. Allow VAL to convert INTEGER to LONGINT. > > Am I correct so far? Yes, correct. This is what is now implemented in the CVS head. > Now, what to do about converting from LONGINT to INTEGER? > a. Originally, ORD was proposed along with use of a checked runtime error if the value of the LONGINT didn?t fit into an INTEGER. But, then the result type signature of ORD (i.e., INTEGER) doesn?t preserve the identity ORD(n) = VAL(n, T) = n when T is LONGINT. To allow this, you would have to make the result type of ORD dependent on the parameter type passed to ORD. See above. > b. Provide an overloaded form of VAL with a different signature that allows for int := VAL(longInt, INTEGER). I think this is somewhat confusing in terms of the original definition of VAL as an inverse of ORD. See above. > c. Allow for checked assignability, e.g., int := longInt; but then this to me starts us on the slippery slope where one eventually argues for mixed arithmetic. No assignability! > d. Come up with differently named operators (different from ORD/VAL). These would have the benefit of requiring only one parameter, whereas VAL requires two, and would prevent any confusion with the defined use of ORD/VAL as conversion inverses for enumerations and integers. This is my preferred option. I don't think we need to do this, assuming you understand what I have said above. ORD(x: INTEGER): LONGINT ORD(x: LONGINT): INTEGER ORD(x: Enumeration): INTEGER ORD(x: Subrange): Base(Subrange) ORD(n) = VAL(n, T) = n if n is an integer of type T = INTEGER or T = LONGINT. > e. Any other ideas? I think we are done... > > Regards, > Randy > > From: Tony Hosking [mailto:hosking at cs.purdue.edu] > Sent: Monday, January 11, 2010 12:32 PM > To: Randy Coleburn > Cc: m3devel > Subject: Re: [M3devel] the LONGINT proposal > > Quick summary: > > I agree, and you seem to be supporting the status quo (other than your discomfort with ORD/VAL) as defined at: http://www.cs.purdue.edu/homes/hosking/m3/reference/ > > On 11 Jan 2010, at 01:11, Randy Coleburn wrote: > > > Tony: > > Sorry, I have been too long-winded here. To answer your questions succinctly: > > 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. > > Agreed. > > > > 2. I think checked assignability gets us onto the slippery slope (see below). Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. > > Read on for the long-winded version? > > According to NELSON (SPwM3), ORD and VAL convert between enumerations and INTEGERs, and INTEGER is all integers represented by the implementation. So, the range of INTEGER is likely different for 8-bit, 16-bit, 32-bit, and 64-bit processors. > > Today we see 32-bit and 64-bit processors as predominant, but I remember the day when 8-bit and 16-bit were the norm. Someday we may see 128-bit processors as the norm. > > (I?ve been cleaning up my basement office and ran across a box of 8-inch floppy disks. When I showed them to my daughter she understood the meaning of ?floppy? as opposed to the rigid 3.5-inch floppies of today. But, I digress.) > > On a 64-bit processor, this whole idea of LONGINT as 64-bits then becomes mute since INTEGER will be 64 bits also. But on a 16-bit machine (assuming we had an implementation for one) the native word size would be less than the 32-bits we seem to take for granted now. > > One problem is that one doesn?t really know the range of LONGINT unless we define it as some number of bits. Rodney?s proposal simply stated that LONGINT was at least as big as INTEGER but could be larger. So, on a 64-bit machine, are LONGINT and INTEGER really the same in terms of implementation?, whereas on a 32-bit the LONGINT would have an additional 32-bits more than INTEGER? What about a 128-bit machine? > > What's wrong with using FIRST(LONGINT) and LAST(LONGINT) to determine the range? This is currently implemented. > On a 64-bit machine the types LONGINT and INTEGER are still distinct in the current implementation, so cannot be assigned, though they do happen to have the same underlying representation. > > > I say all this to point out the obvious, namely that LONGINT and INTEGER are different types. > > Correct. The current implementation treats them as completely separate. > > > Therefore, IMO the language must make it clear how these different types interact. > > I would argue that > x: LONGINT := 23; > is wrong! The programmer should have to write > x: LONGINT := 23L; > instead. > > This is what we currently implement. > > > A subrange of LONGINT would be written as [23L..4200L] and would be a different type than the integer subrange [23..4200] even though the ranges are identical. > > Also what we currently implement. > > > Likewise, IMO mixed arithmetic with the compiler deciding what to do is wrong. The programmer should have to explicitly write conversions to a common type for arithmetic. > > I agree, and this is the current implementation. > > > I have no problem with extending the existing operators to deal with LONGINT; it?s just that the result should be LONGINT. > Given x: LONGINT := 49L; > INC(x) yields 50L > INC(x, 3L) yields 52L > note that INC(x, 3) would be a syntax error since 3 is an INTEGER and x is a LONGINT > (x + 20L) yields 69L > note that (x + 20) would be a syntax error since 20 is an INTEGER and x is a LONGINT > LAST(LONGINT) yields a LONGINT > > This is exactly the current implementation. > > > Now that I think about it more, I have a problem using ORD/VAL for the conversion since NELSON defines these as converting between enumerations and INTEGERs, and since LONGINT is a different type than INTEGER and quite possibly has a greater range than INTEGER. Is the proposal to also allow enumerations to use the range of LONGINT ? Enumerations currently are defined as having a range no greater than INTEGER. To extend them to LONGINT would lose the obvious performance benefits of keeping them same range as native INTEGER. > > I'm not sure that the current implementation conflicts with the definition of ORD/VAL. What we currently permit is ORD(LONGINT) to do a *checked* conversion of a LONGINT to an INTEGER. The optional type parameter of VAL can be LONGINT, which permits conversion of INTEGER to LONGINT. I don't see how these conflict with the intention of ORD/VAL. You can see the language spec for what is currently implemented at: http://www.cs.purdue.edu/~hosking/m3/reference/. > > > Maybe we should invent new names for the conversions between INTEGER and LONGINT. Perhaps PROMOTE and DEMOTE or some such. These are probably bad names, but I use them below simply to illustrate (feel free to come up with better names): > Given longInt: LONGINT; and int: INTEGER; > int := DEMOTE(longInt); would perform the conversion from LONGINT to INTEGER and would give a runtime range check error if longInt is too big/small to fit in an INTEGER. > longInt := PROMOTE(int) would always succeed in performing the conversion from INTEGER to LONGINT but would make the conversion explicit > int + DEMOTE(longInt) would yield an INTEGER result with all arithmetic being done in the range of INTEGER > longInt + PROMOTE(int) would yield a LONGINT result with all arithmetic being done in the range of LONGINT > > I think ORD/VAL suffice... > > > Now if we were to allow checked assignability (as Tony is leaning toward), I think we begin to get on the slippery slope. How far do we extend this to the point that it is not clear in the expression of the code what is happening? If I can write ?int := longInt;? why not ?int := 23L;? and why not ?int := longInt + 57;? and is this different than ?int := longInt + 57L;?? etc. etc. > > I agree the ORD/VAL syntax is ugly, so that is another reason (besides them applying to enumerations only) we should use different names for the INTEGER/LONGINT conversions. > > Sorry, I have been too long-winded here. To answer your questions succinctly: > > 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. > > 2. I think checked assignability gets us onto the slippery slope. Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. > > Regards, > Randy Coleburn > > From: Tony Hosking [mailto:hosking at cs.purdue.edu] > Sent: Sunday, January 10, 2010 3:43 PM > To: Randy Coleburn > Cc: m3devel > Subject: Re: [M3devel] the LONGINT proposal > > Hi Randy, > > As someone who has actually written Modula-3 programs for a living your opinions are always highly valued. I agree with you in principle and aims, except for requiring overflow to be a checked run-time error. The language definition already has a mechanism for handling this in the require FloatMode interface. It is not something that the compiler should be involved in. I also just now raised a question about perhaps having integer literals adapt their type to the context in which they are used. > > I should point out that the current mainline implementation does exactly what you propose (except overflow checking). It captures the fundamental spirit of Rodney's proposal but does not permit mixed arithmetic or assignment. Can I ask what your issue is w.r.to checked assignability? I am still leaning in favor. It is not much different from assignment from an INTEGER to a subrange, which requires no explicit check, though of course there is a run-time range check. Having programmers explicitly write: > > x: INTEGER := ORD(longint, INTEGER); > > seems unnecessary when they could just write > > x: INTEGER := longint; > > This is similar in spirit to: > > x: [lo..hi] := integer; > > > On 10 Jan 2010, at 15:00, Randy Coleburn wrote: > > > > I've been trying to follow along on this topic. > > Here are my thoughts: > > 1. LONGINT should be a distinct type different from INTEGER. > > 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. > > 3. Overflow should be a checked run-time error, not silently wrapped around. > > 4. WRT assignability, I think explicit conversions should be used. > > These statements may make me unpopular with some who don't like to type much, but I've always hated the tradeoff of understandability for brevity in expression. > > The important thing is not how fast we can type up a program, it is rather how hard is it to make a mistake. I think the spirit of Modula-3 is that the language makes you a better programmer by forcing you to make your intentions explicit rather than relying on the compiler to infer your intentions. We need correct and maintainable software, especially at the systems level. Whatever is decided about LONGINT, we need to keep to the original design tenants of the language. > > And yes, I do think we need a LONGINT type, not just to deal with large file sizes. > > But even for long-lived readers/writers, whatever type you choose for the index will eventually be insufficient, so you have to code for the possibility that the range of the long lived reader/writer exceeds the range of your index type. That is just good programming. > > I think sometimes that the new generation of programmers has been warped by what I call the "Microsoft Mentality" where you must expect that you need to reboot/restart every so often to maintain proper performance. Programs should be written to run forever or until their job is completed or they are commanded to stop. > > As "we" begin to converge on the design changes, I like having something concrete to look at, ala Rodney's proposal. Can we take that and keep tweaking it in these emails until we reach a final version acceptable to all? To me this keeps the discussion focused rather than the many different emails. Thus, what I am trying to say is put forth a numbered proposal and each subsequent email must show adjustment to that proposal rather than just a bunch of emails discussing various aspects. Perhaps we should vote on each proposed change, then decide to call a final vote on the whole thing. Who should be involved in such votes? Right now the main persons on the thread are Tony, Jay, Rodney, Mika, Hendrik, Olaf, John, and me. > > My two cents. > > Regards, > Randy Coleburn > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Jan 12 04:50:05 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 22:50:05 -0500 Subject: [M3devel] 64bit file sizes now? In-Reply-To: <420956.32527.qm@web23605.mail.ird.yahoo.com> References: <420956.32527.qm@web23605.mail.ird.yahoo.com> Message-ID: <0EB89E7A-0804-4D07-9F80-CB1F5A343471@cs.purdue.edu> Overflow checking is a whole other ball of wax... ;-) The language reference provides for controlling the behavior of integer operations regarding overflow and divide by zero through the interface FloatMode.i3. Unfortunately, the implementation of this interface on many targets is incomplete and the default behaviour is to allow integer operations to silently overflow. Range checks are still injected by the compiler to ensure that no variable has a bit representation that is not a legal value for that variable. Thus, for example: VAR x: INTEGER := LAST(INTEGER)+1 will leave x with the value -1. But, VAR x: CARDINAL := LAST(INTEGER)+1 will cause a range fault because the overflowed result is not a legal CARDINAL. It would be great if someone could devote some time to implementing this interface for x86 or x86_64 as they are the most widely used these days. Of course, each OS target will probably need a different implementation. On 11 Jan 2010, at 22:27, Daniel Alejandro Benavides D. wrote: > Hi all: > forgive my ignorance of current discussion and implementation of LONGINT but I read something about arithmetic overflow; I didn't feel was reasonable even if the current implementation doesn't support arithmetic overflow checks, I must say we can't assume this expression: > (LAST(INTEGER) + 1) = FIRST (INTEGER) > This sort expression by itself should be catched at compile or run time as an execution error as any CPU would halt in such a case of division by zero, or at least a flag (an exception, etc). > Nonetheless writing code in CM3 that exploit this restriction would be useless in M3 systems with overflow checking, so I really want to say that at least we can't assume M3 code to do this kind of "assumptions". It other words this is unsafe. I don't how far would people like to have checks on arithmetic expressions, what do you think of creating a compiler option to generate arithmetic overflow check code. > Please let me know if I'm wrong about this issue on current discussions. > > --- El lun, 11/1/10, Jay K escribi?: > >> De: Jay K >> Asunto: [M3devel] 64bit file sizes now? >> Para: "m3devel" >> Fecha: lunes, 11 de enero, 2010 22:02 >> >> >> >> >> >> So.. LONGINT as I understand will remain roughly as it was, >> except VAL(expr, INTEGER) is how you convert expr to >> INTEGER, instead of ORD(expr). >> >> >> >> >> >> And this is already in place. >> >> >> >> >> >> ? >> >> >> >> >> >> So I should go ahead and update File.i3/Status/size and >> Rd/Wr/Index/Seek/Length to all be LONGINT, "whatever >> the consequences"? The consequences are roughly the >> first diff I sent out, with the caveats that I used ORD() >> instead of VAL(,INTEGER), and a few packages were left to >> fix. It is mechanical and simple and predictable, just >> tedious and ugly. >> Most Rd/Wr users are limited to INTEGER "sizes" >> anyway, but a few might gain capacity. >> >> Classic simple example is the mklib and libdump code, they >> read the entire file into memory and then deal with that. >> >> >> >> >> >> I can send the diffs ahead of time, but there's really >> no choices left as to what they'll look like, it is >> forced by the limited capability of LONGINT. >> >> Had they used LONGINT in the first place, of course, >> there'd be no diff at this time, the ugliness would have >> been builtin from the start. >> >> >> >> >> >> - Jay >> >> >> > > > From jay.krell at cornell.edu Tue Jan 12 04:46:13 2010 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Jan 2010 03:46:13 +0000 Subject: [M3devel] 64bit file sizes now? In-Reply-To: <420956.32527.qm@web23605.mail.ird.yahoo.com> References: , <420956.32527.qm@web23605.mail.ird.yahoo.com> Message-ID: True that: > (LAST(INTEGER) + 1) = FIRST (INTEGER) many folks would like to see fail before it gets to the "=". The dilemna remains though because: > (LAST(INTEGER) + 1L) = FIRST (INTEGER) would not fail. So, you can either look at it as they produce different values, or one succeeds and one fails. Either way people don't like two different expressions doing two different things. Again, converting an INTEGER to a LONGINT is one of the simplest things you can do. There something here about "transitivity" or "replacement": j2 := VAL(i1, LONGINT) + j3; vs. j2 := i1 + j3; pretty clearly have the same meaning. The conversion is always trivial and always succeeds. Does anyone really find it ambiguous? - Jay > Date: Tue, 12 Jan 2010 03:27:23 +0000 > From: dabenavidesd at yahoo.es > To: m3devel at elegosoft.com; jay.krell at cornell.edu > Subject: Re: [M3devel] 64bit file sizes now? > > Hi all: > forgive my ignorance of current discussion and implementation of LONGINT but I read something about arithmetic overflow; I didn't feel was reasonable even if the current implementation doesn't support arithmetic overflow checks, I must say we can't assume this expression: > (LAST(INTEGER) + 1) = FIRST (INTEGER) > This sort expression by itself should be catched at compile or run time as an execution error as any CPU would halt in such a case of division by zero, or at least a flag (an exception, etc). > Nonetheless writing code in CM3 that exploit this restriction would be useless in M3 systems with overflow checking, so I really want to say that at least we can't assume M3 code to do this kind of "assumptions". It other words this is unsafe. I don't how far would people like to have checks on arithmetic expressions, what do you think of creating a compiler option to generate arithmetic overflow check code. > Please let me know if I'm wrong about this issue on current discussions. > > --- El lun, 11/1/10, Jay K escribi?: > > > De: Jay K > > Asunto: [M3devel] 64bit file sizes now? > > Para: "m3devel" > > Fecha: lunes, 11 de enero, 2010 22:02 > > > > > > > > > > > > So.. LONGINT as I understand will remain roughly as it was, > > except VAL(expr, INTEGER) is how you convert expr to > > INTEGER, instead of ORD(expr). > > > > > > > > > > > > And this is already in place. > > > > > > > > > > > > ? > > > > > > > > > > > > So I should go ahead and update File.i3/Status/size and > > Rd/Wr/Index/Seek/Length to all be LONGINT, "whatever > > the consequences"? The consequences are roughly the > > first diff I sent out, with the caveats that I used ORD() > > instead of VAL(,INTEGER), and a few packages were left to > > fix. It is mechanical and simple and predictable, just > > tedious and ugly. > > Most Rd/Wr users are limited to INTEGER "sizes" > > anyway, but a few might gain capacity. > > > > Classic simple example is the mklib and libdump code, they > > read the entire file into memory and then deal with that. > > > > > > > > > > > > I can send the diffs ahead of time, but there's really > > no choices left as to what they'll look like, it is > > forced by the limited capability of LONGINT. > > > > Had they used LONGINT in the first place, of course, > > there'd be no diff at this time, the ugliness would have > > been builtin from the start. > > > > > > > > > > > > - Jay > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Tue Jan 12 04:57:38 2010 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 11 Jan 2010 22:57:38 -0500 Subject: [M3devel] 64bit file sizes now? In-Reply-To: References: , <420956.32527.qm@web23605.mail.ird.yahoo.com> Message-ID: <770FAFA3-9F41-48F4-A2E0-D4CD947EE6D2@cs.purdue.edu> On 11 Jan 2010, at 22:46, Jay K wrote: > True that: > > > (LAST(INTEGER) + 1) = FIRST (INTEGER) > > > many folks would like to see fail before it gets to the "=". WIthout overflow checking the addition will not fail. > > The dilemna remains though because: > > > (LAST(INTEGER) + 1L) = FIRST (INTEGER) Actually, you mean VAL(LAST(INTEGER), LONGINT) + 1L > would not fail. > > So, you can either look at it as they produce different values, or one succeeds and one fails. The point is that the type explicitly tells you whether you might be in trouble with overflow. > Either way people don't like two different expressions doing two different things. > Again, converting an INTEGER to a LONGINT is one of the simplest things you can do. > > There something here about "transitivity" or "replacement": > > j2 := VAL(i1, LONGINT) + j3; > vs. > j2 := i1 + j3; It is not referentially transparent. It requires innate knowledge about promotion rules to understand. That's what "not referentially transparent" means! > > pretty clearly have the same meaning. > The conversion is always trivial and always succeeds. > Does anyone really find it ambiguous? > > - Jay > > > > Date: Tue, 12 Jan 2010 03:27:23 +0000 > > From: dabenavidesd at yahoo.es > > To: m3devel at elegosoft.com; jay.krell at cornell.edu > > Subject: Re: [M3devel] 64bit file sizes now? > > > > Hi all: > > forgive my ignorance of current discussion and implementation of LONGINT but I read something about arithmetic overflow; I didn't feel was reasonable even if the current implementation doesn't support arithmetic overflow checks, I must say we can't assume this expression: > > (LAST(INTEGER) + 1) = FIRST (INTEGER) > > This sort expression by itself should be catched at compile or run time as an execution error as any CPU would halt in such a case of division by zero, or at least a flag (an exception, etc). > > Nonetheless writing code in CM3 that exploit this restriction would be useless in M3 systems with overflow checking, so I really want to say that at least we can't assume M3 code to do this kind of "assumptions". It other words this is unsafe. I don't how far would people like to have checks on arithmetic expressions, what do you think of creating a compiler option to generate arithmetic overflow check code. > > Please let me know if I'm wrong about this issue on current discussions. > > > > --- El lun, 11/1/10, Jay K escribi?: > > > > > De: Jay K > > > Asunto: [M3devel] 64bit file sizes now? > > > Para: "m3devel" > > > Fecha: lunes, 11 de enero, 2010 22:02 > > > > > > > > > > > > > > > > > > So.. LONGINT as I understand will remain roughly as it was, > > > except VAL(expr, INTEGER) is how you convert expr to > > > INTEGER, instead of ORD(expr). > > > > > > > > > > > > > > > > > > And this is already in place. > > > > > > > > > > > > > > > > > > ? > > > > > > > > > > > > > > > > > > So I should go ahead and update File.i3/Status/size and > > > Rd/Wr/Index/Seek/Length to all be LONGINT, "whatever > > > the consequences"? The consequences are roughly the > > > first diff I sent out, with the caveats that I used ORD() > > > instead of VAL(,INTEGER), and a few packages were left to > > > fix. It is mechanical and simple and predictable, just > > > tedious and ugly. > > > Most Rd/Wr users are limited to INTEGER "sizes" > > > anyway, but a few might gain capacity. > > > > > > Classic simple example is the mklib and libdump code, they > > > read the entire file into memory and then deal with that. > > > > > > > > > > > > > > > > > > I can send the diffs ahead of time, but there's really > > > no choices left as to what they'll look like, it is > > > forced by the limited capability of LONGINT. > > > > > > Had they used LONGINT in the first place, of course, > > > there'd be no diff at this time, the ugliness would have > > > been builtin from the start. > > > > > > > > > > > > > > > > > > - Jay > > > > > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rcolebur at SCIRES.COM Tue Jan 12 05:09:46 2010 From: rcolebur at SCIRES.COM (Randy Coleburn) Date: Mon, 11 Jan 2010 23:09:46 -0500 Subject: [M3devel] the LONGINT proposal In-Reply-To: <26567A2B-DF4C-460C-A06C-3C534731FA53@cs.purdue.edu> References: <20100110051218.2F3C42474001@birch.elegosoft.com> <73D2F123-F308-4210-9655-1F80F9A5C370@cs.purdue.edu> <2158B017-4405-40B6-A750-FAD2BAA88BCB@cs.purdue.edu> <26567A2B-DF4C-460C-A06C-3C534731FA53@cs.purdue.edu> Message-ID: Tony: I'm sorry, I missed the fact that you changed the type to "Integer" vs. "INTEGER" and defined "Integer" to be "INTEGER" or "LONGINT". I agree that with your changes everything is in order now, even though I would prefer different names. Nevertheless, I can be "happy" with this state of affairs. I am confused though by your last set of statements, namely: >I don't think we need to do this, assuming you understand what I have said above. > >ORD(x: INTEGER): LONGINT >ORD(x: LONGINT): INTEGER >ORD(x: Enumeration): INTEGER >ORD(x: Subrange): Base(Subrange) > >ORD(n) = VAL(n, T) = n if n is an integer of type T = INTEGER or T = LONGINT. Didn't you mean: ORD(x:INTEGER): INTEGER ORD(x:LONGINT): LONGINT Also, in case anyone is interested, the current HEAD fails to compile the following packages on Windows Vista: "m3-libs\m3core" "m3-libs\libm3" "m3-tools\m3tk" So some recent changes have caused a problem. Regards, Randy From: Tony Hosking [mailto:hosking at cs.purdue.edu] Sent: Monday, January 11, 2010 10:40 PM To: Randy Coleburn Cc: m3devel Subject: Re: [M3devel] the LONGINT proposal On 11 Jan 2010, at 22:11, Randy Coleburn wrote: Tony et al: Yes, I think I am supporting the "status quo", which seems to be Rodney's proposal, minus mixed arithmetic and checked assignability; plus my discomfort with ORD/VAL as you state. (See discussion below to the end for more on this "discomfort" and the problem I see with converting from LONGINT to INTEGER.) When I said we don't know the range of LONGINT, I meant that in the context of documenting the language we weren't specifying this range; rather it is implementation-defined. Indeed, yes you must be able to do FIRST(LONGINT) and LAST(LONGINT) at runtime to determine the actual range. Tony you stated in your response that the 2nd parameter (the type) of VAL is optional. I was not aware that this parameter can be defaulted. Where is this stated in the language spec? Sorry, my error. I realised after writing that I had mis-spoken. I've only scanned your HTML reference briefly, but it seems to me that even there it still says that ORD/VAL convert between enumerations and INTEGERs, not LONGINTs. That wording is exactly the same as it has always been. Here is the diff from the original specification (before LONGINT): 55,56c55,56 < ORD (element: Ordinal): INTEGER < VAL (i: INTEGER; T: OrdinalType): T --- > ORD (element: Ordinal): Integer > VAL (i: Integer; T: OrdinalType): T 74c74 < If n is an integer, ORD(n) = VAL(n, INTEGER) = n. --- > If n is an integer of type T, ORD(n) = VAL(n, T) = n. Notice that all that I have changed is to allow ORD to return INTEGER or LONGINT, depending on the type of the element. And VAL simply takes an INTEGER or LONGINT and converts to an Ordinal type T. Are we going to allow LONGINT to be an enumeration? If so, then why not go full bore and just make INTEGER a subrange of LONGINT? (I don't favor this.) No, enumerations map only onto INTEGER. Alternately, if you want to use ORD/VAL for the LONGINT conversions, could we at least change 2.2.1 to say that ORD/VAL convert between ordinal types, since enumerations are defined as an ordinal type and LONGINT falls into the category of an ordinal type, but not an enumeration type? Indeed, the syntax definition of ORD/VAL seem to bear out this fact even though the text references "enumerations" (see 4th major paragraph in 2.2.1, "The operators ORD and VAL convert between ..."). I don't want to make wholesale changes to the reference that were not there in the first place. ORD applied to and INTEGER has always been the identity operation. The syntax of ORD/VAL is: ORD (element: Ordinal): Integer VAL (i: Integer; T: OrdinalType): T and, if n is a integer of type T, ORD(n) = VAL(n, T) = n. BTW: I think the above identity should say that n is a non-negative integer! Huh? No, that is not the case. It is only non-negative for enumerations which count from 0. So, using these, you propose one would write longInt := VAL(int, LONGINT); int := ORD(longInt) No, longint := VAL(integer, LONGINT) integer := VAL(longint, INTEGER) int := ORD(int) longint := ORD(longint) then, the identity doesn't exactly match up unless you allow ORD(longInt) to return a LONGINT, but then if you do that the signature of ORD must be dependent on its argument type (either INTEGER or LONGINT; note that enumerations and INTEGER subranges also yield type INTEGER). This captures the identities precisely, which is why I reverted to the original formulation. Therefore, in the case of argument LONGINT, the type of the LHS of ORD must be a LONGINT; and the LHS type must be INTEGER when the argument is INTEGER, unless you allow checked assignability, in which case why do you need ORD in the first place? IMO, ORD/VAL make more sense in the case of enumerations. For example: Color = (Red, Blue, Green); ORD(Color.Blue) = 1 VAL(1, Color) = Color.Blue (Note that the identity doesn't apply here since n isn't an integer when applied to ORD, or to the result of VAL.) Yes, of course, ORD/VAL are there to allow mapping of enumerations to INTEGER. But, for general consistency any integer can have ORD applied to it, and any integer can be mapped to its own type. I think I saw later in one of the commit messages or replies to Jay that you propose to drop use of ORD with LONGINT and just use VAL, as in: longInt := VAL(int, LONGINT); int := VAL(longInt, INTEGER); That is what is now implemented. but the second form would violate the signature of VAL, which requires an INTEGER as the first argument. No, notice that VAL takes an Integer which can be INTEGER or LONGINT typed. I guess my heartburn with using ORD/VAL for LONGINT conversions stems from fact that before LONGINT, enumerations, subranges, and INTEGER all had the same maximum range and NELSON states that ORD/VAL are for conversions between enumerations (aka ordinals) and integers. Note that NELSON uses lowercase "integers" (should really be "non-negative integers") so I guess this could mean all non-negative integers, whether representable as INTEGER or LONGINT, but then there was no LONGINT when NELSON's book came out. Also, before LONGINT, ORD could not cause a checked runtime error. ORD now can never cause a checked runtime error, just as with Nelson. So, at this point, to summarize, I think you are advocating: 1. Distinct types INTEGER and LONGINT. 2. LONGINT is an ordinal type, but cannot be used as the index type for an array. 3. Enumerations are still constrained to no more than NUMBER(CARDINAL) total values, i.e., (LAST(INTEGER)+1). 4. No mixed arithmetic between INTEGER and LONGINT; require explicit conversions. 5. No mixed comparisons between INTEGER and LONGINT; require explicit conversions. 6. Allow VAL to convert INTEGER to LONGINT. Am I correct so far? Yes, correct. This is what is now implemented in the CVS head. Now, what to do about converting from LONGINT to INTEGER? a. Originally, ORD was proposed along with use of a checked runtime error if the value of the LONGINT didn't fit into an INTEGER. But, then the result type signature of ORD (i.e., INTEGER) doesn't preserve the identity ORD(n) = VAL(n, T) = n when T is LONGINT. To allow this, you would have to make the result type of ORD dependent on the parameter type passed to ORD. See above. b. Provide an overloaded form of VAL with a different signature that allows for int := VAL(longInt, INTEGER). I think this is somewhat confusing in terms of the original definition of VAL as an inverse of ORD. See above. c. Allow for checked assignability, e.g., int := longInt; but then this to me starts us on the slippery slope where one eventually argues for mixed arithmetic. No assignability! d. Come up with differently named operators (different from ORD/VAL). These would have the benefit of requiring only one parameter, whereas VAL requires two, and would prevent any confusion with the defined use of ORD/VAL as conversion inverses for enumerations and integers. This is my preferred option. I don't think we need to do this, assuming you understand what I have said above. ORD(x: INTEGER): LONGINT ORD(x: LONGINT): INTEGER ORD(x: Enumeration): INTEGER ORD(x: Subrange): Base(Subrange) ORD(n) = VAL(n, T) = n if n is an integer of type T = INTEGER or T = LONGINT. e. Any other ideas? I think we are done... Regards, Randy From: Tony Hosking [mailto:hosking at cs.purdue.edu] Sent: Monday, January 11, 2010 12:32 PM To: Randy Coleburn Cc: m3devel Subject: Re: [M3devel] the LONGINT proposal Quick summary: I agree, and you seem to be supporting the status quo (other than your discomfort with ORD/VAL) as defined at: http://www.cs.purdue.edu/homes/hosking/m3/reference/ On 11 Jan 2010, at 01:11, Randy Coleburn wrote: Tony: Sorry, I have been too long-winded here. To answer your questions succinctly: 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. Agreed. 2. I think checked assignability gets us onto the slippery slope (see below). Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. Read on for the long-winded version... According to NELSON (SPwM3), ORD and VAL convert between enumerations and INTEGERs, and INTEGER is all integers represented by the implementation. So, the range of INTEGER is likely different for 8-bit, 16-bit, 32-bit, and 64-bit processors. Today we see 32-bit and 64-bit processors as predominant, but I remember the day when 8-bit and 16-bit were the norm. Someday we may see 128-bit processors as the norm. (I've been cleaning up my basement office and ran across a box of 8-inch floppy disks. When I showed them to my daughter she understood the meaning of "floppy" as opposed to the rigid 3.5-inch floppies of today. But, I digress.) On a 64-bit processor, this whole idea of LONGINT as 64-bits then becomes mute since INTEGER will be 64 bits also. But on a 16-bit machine (assuming we had an implementation for one) the native word size would be less than the 32-bits we seem to take for granted now. One problem is that one doesn't really know the range of LONGINT unless we define it as some number of bits. Rodney's proposal simply stated that LONGINT was at least as big as INTEGER but could be larger. So, on a 64-bit machine, are LONGINT and INTEGER really the same in terms of implementation?, whereas on a 32-bit the LONGINT would have an additional 32-bits more than INTEGER? What about a 128-bit machine? What's wrong with using FIRST(LONGINT) and LAST(LONGINT) to determine the range? This is currently implemented. On a 64-bit machine the types LONGINT and INTEGER are still distinct in the current implementation, so cannot be assigned, though they do happen to have the same underlying representation. I say all this to point out the obvious, namely that LONGINT and INTEGER are different types. Correct. The current implementation treats them as completely separate. Therefore, IMO the language must make it clear how these different types interact. I would argue that x: LONGINT := 23; is wrong! The programmer should have to write x: LONGINT := 23L; instead. This is what we currently implement. A subrange of LONGINT would be written as [23L..4200L] and would be a different type than the integer subrange [23..4200] even though the ranges are identical. Also what we currently implement. Likewise, IMO mixed arithmetic with the compiler deciding what to do is wrong. The programmer should have to explicitly write conversions to a common type for arithmetic. I agree, and this is the current implementation. I have no problem with extending the existing operators to deal with LONGINT; it's just that the result should be LONGINT. Given x: LONGINT := 49L; INC(x) yields 50L INC(x, 3L) yields 52L note that INC(x, 3) would be a syntax error since 3 is an INTEGER and x is a LONGINT (x + 20L) yields 69L note that (x + 20) would be a syntax error since 20 is an INTEGER and x is a LONGINT LAST(LONGINT) yields a LONGINT This is exactly the current implementation. Now that I think about it more, I have a problem using ORD/VAL for the conversion since NELSON defines these as converting between enumerations and INTEGERs, and since LONGINT is a different type than INTEGER and quite possibly has a greater range than INTEGER. Is the proposal to also allow enumerations to use the range of LONGINT ? Enumerations currently are defined as having a range no greater than INTEGER. To extend them to LONGINT would lose the obvious performance benefits of keeping them same range as native INTEGER. I'm not sure that the current implementation conflicts with the definition of ORD/VAL. What we currently permit is ORD(LONGINT) to do a *checked* conversion of a LONGINT to an INTEGER. The optional type parameter of VAL can be LONGINT, which permits conversion of INTEGER to LONGINT. I don't see how these conflict with the intention of ORD/VAL. You can see the language spec for what is currently implemented at: http://www.cs.purdue.edu/~hosking/m3/reference/. Maybe we should invent new names for the conversions between INTEGER and LONGINT. Perhaps PROMOTE and DEMOTE or some such. These are probably bad names, but I use them below simply to illustrate (feel free to come up with better names): Given longInt: LONGINT; and int: INTEGER; int := DEMOTE(longInt); would perform the conversion from LONGINT to INTEGER and would give a runtime range check error if longInt is too big/small to fit in an INTEGER. longInt := PROMOTE(int) would always succeed in performing the conversion from INTEGER to LONGINT but would make the conversion explicit int + DEMOTE(longInt) would yield an INTEGER result with all arithmetic being done in the range of INTEGER longInt + PROMOTE(int) would yield a LONGINT result with all arithmetic being done in the range of LONGINT I think ORD/VAL suffice... Now if we were to allow checked assignability (as Tony is leaning toward), I think we begin to get on the slippery slope. How far do we extend this to the point that it is not clear in the expression of the code what is happening? If I can write "int := longInt;" why not "int := 23L;" and why not "int := longInt + 57;" and is this different than "int := longInt + 57L;"? etc. etc. I agree the ORD/VAL syntax is ugly, so that is another reason (besides them applying to enumerations only) we should use different names for the INTEGER/LONGINT conversions. Sorry, I have been too long-winded here. To answer your questions succinctly: 1. I can relax on the requirement for overflow checking, but programmers should never count on it silently wrapping around. 2. I think checked assignability gets us onto the slippery slope. Using differently named conversion operators would lesson some of the ugliness of ORD/VAL and also prevent confusion with their intended use as enumeration/INTEGER conversions. Regards, Randy Coleburn From: Tony Hosking [mailto:hosking at cs.purdue.edu] Sent: Sunday, January 10, 2010 3:43 PM To: Randy Coleburn Cc: m3devel Subject: Re: [M3devel] the LONGINT proposal Hi Randy, As someone who has actually written Modula-3 programs for a living your opinions are always highly valued. I agree with you in principle and aims, except for requiring overflow to be a checked run-time error. The language definition already has a mechanism for handling this in the require FloatMode interface. It is not something that the compiler should be involved in. I also just now raised a question about perhaps having integer literals adapt their type to the context in which they are used. I should point out that the current mainline implementation does exactly what you propose (except overflow checking). It captures the fundamental spirit of Rodney's proposal but does not permit mixed arithmetic or assignment. Can I ask what your issue is w.r.to checked assignability? I am still leaning in favor. It is not much different from assignment from an INTEGER to a subrange, which requires no explicit check, though of course there is a run-time range check. Having programmers explicitly write: x: INTEGER := ORD(longint, INTEGER); seems unnecessary when they could just write x: INTEGER := longint; This is similar in spirit to: x: [lo..hi] := integer; On 10 Jan 2010, at 15:00, Randy Coleburn wrote: I've been trying to follow along on this topic. Here are my thoughts: 1. LONGINT should be a distinct type different from INTEGER. 2. There should be no mixed arithmetic between the types. The programmer must code conversions using ORD/VAL to make explicit the intention. Don't rely on some ill-remembered built-in conversion rule. 3. Overflow should be a checked run-time error, not silently wrapped around. 4. WRT assignability, I think explicit conversions should be used. These statements may make me unpopular with some who don't like to type much, but I've always hated the tradeoff of understandability for brevity in expression. The important thing is not how fast we can type up a program, it is rather how hard is it to make a mistake. I think the spirit of Modula-3 is that the language makes you a better programmer by forcing you to make your intentions explicit rather than relying on the compiler to infer your intentions. We need correct and maintainable software, especially at the systems level. Whatever is decided about LONGINT, we need to keep to the original design tenants of the language. And yes, I do think we need a LONGINT type, not just to deal with large file sizes. But even for long-lived readers/writers, whatever type you choose for the index will eventually be insufficient, so you have to code for the possibility that the range of the long lived reader/writer exceeds the range of your index type. That is just good programming. I think sometimes that the new generation of programmers has been warped by what I call the "Microsoft Mentality" where you must expect that you need to reboot/restart every so often to maintain proper performance. Programs should be written to run forever or until their job is completed or they are commanded to stop. As "we" begin to converge on the design changes, I like having something concrete to look at, ala Rodney's proposal. Can we take that and keep tweaking it in these emails until we reach a final version acceptable to all? To me this keeps the discussion focused rather than the many different emails. Thus, what I am trying to say is put forth a numbered proposal and each subsequent email must show adjustment to that proposal rather than just a bunch of emails discussing various aspects. Perhaps we should vote on each proposed change, then decide to call a final vote on the whole thing. Who should be involved in such votes? Right now the main persons on the thread are Tony, Jay, Rodney, Mika, Hendrik, Olaf, John, and me. My two cents. Regards, Randy Coleburn -------------- next part -------------- An HTML attachment was scrubbed... URL: From jdp at polstra.com Tue Jan 12 05:43:50 2010 From: jdp at polstra.com (John Polstra) Date: Mon, 11 Jan 2010 20:43:50 -0800 Subject: [M3devel] Fwd: CM3 development Inquiry. In-Reply-To: <9997AE9B-BB65-4B2E-9528-D002583C8B97@cs.purdue.edu> References: <20100110164332.0c09a257.dimonax@att.net> <5A44E4F2-AF0C-4241-BD11-4A8B0912A022@cs.purdue.edu> <20100111115257.d437knapzgocgc0g@mail.elegosoft.com> <9997AE9B-BB65-4B2E-9528-D002583C8B97@cs.purdue.edu> Message-ID: <4B4BFE06.5010400@polstra.com> I forwarded this to him, and my mail log says it was delivered. John Tony Hosking wrote: > Actually, that diagnostic indicates that scc-mailrelay.att.net > is blocking messages from the Elegosoft > mail server (it is blacklisted!). > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On 11 Jan 2010, at 05:52, Olaf Wagner wrote: > >> Quoting Tony Hosking > >: >> >>> This guy is trying to subscribe to m3devel. Can someone help him? >>> >>> Begin forwarded message: >>> >>>> From: Chris > >>>> Date: 10 January 2010 16:43:32 EST >>>> To: Tony Hosking > >>>> Subject: Re: CM3 development Inquiry. >>>> >>>> On Fri, 8 Jan 2010 13:01:21 -0500 >>>> Tony Hosking > >>>> wrote: >>>> >>>>> Did you manage to subscribe? >>>> >>>> I put in another subscription request just after your previous >>>> reply, and I'm still waiting. I wonder if the confirmation e-mail >>>> is getting through. Nonetheless, I'll keep trying. >> >> Unfortunately the address does not work: >> >> This is the mail system at host mx0.elegosoft.com >> . >> >> I'm sorry to have to inform you that your message could not >> be delivered to one or more recipients. It's attached below. >> >> For further assistance, please send mail to postmaster. >> >> If you do so, please include this problem report. You can >> delete your own text from the attached returned message. >> >> The mail system >> >> >: host >> scc-mailrelay.att.net[204.127.208.75] said: >> 521-88.198.54.133 blocked by sbc:blacklist.mailrelay.att.net. 521 >> DNSRBL: >> Blocked for abuse. See http://att.net/blocks (in reply to MAIL FROM >> command) >> >> If he really wants to join, he needs another mail address, but I cannot >> tell him that. >> >> Olaf >> -- >> Olaf Wagner -- elego Software Solutions GmbH >> Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany >> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 >> 86 95 >> http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin >> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: >> DE163214194 >> > From jay.krell at cornell.edu Tue Jan 12 05:55:25 2010 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Jan 2010 04:55:25 +0000 Subject: [M3devel] FloatMode In-Reply-To: <770FAFA3-9F41-48F4-A2E0-D4CD947EE6D2@cs.purdue.edu> References: , <420956.32527.qm@web23605.mail.ird.yahoo.com> , <770FAFA3-9F41-48F4-A2E0-D4CD947EE6D2@cs.purdue.edu> Message-ID: I thought FloatMode was only related to floating point. So I looked: "IntOverflow" = an integer operation produced a result whose absolute value is too large to be represented. "IntDivByZero" = integer "DIV" or "MOD" by zero. \end{quote} This part of it should be easy to implement for all architectures. The entire thing probably isn't too difficult either on many platforms either. However...I was surprised by this. I thought the real "intent" in Modula-3 to not have this be configurable and endeavor for overflow and divide by zero to always immediately raise an exception? The only "out" is that it might not get implemented on some platforms for some reason? For the floating point stuff: Probably like other per-platform code, this should be done in #ifdefed C. http://msdn.microsoft.com/en-us/library/e9b52ceh(VS.80).aspx http://kernel.org/doc/man-pages/online/pages/man3/fetestexcept.3.html etc. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From rcolebur at SCIRES.COM Tue Jan 12 05:59:01 2010 From: rcolebur at SCIRES.COM (Randy Coleburn) Date: Mon, 11 Jan 2010 23:59:01 -0500 Subject: [M3devel] Fwd: CM3 development Inquiry. In-Reply-To: <4B4BFE06.5010400@polstra.com> References: <20100110164332.0c09a257.dimonax@att.net> <5A44E4F2-AF0C-4241-BD11-4A8B0912A022@cs.purdue.edu> <20100111115257.d437knapzgocgc0g@mail.elegosoft.com> <9997AE9B-BB65-4B2E-9528-D002583C8B97@cs.purdue.edu> <4B4BFE06.5010400@polstra.com> Message-ID: I also took the liberty of contacting him. Shown below is my message and his response: Regards, Randy On Mon, 11 Jan 2010 12:19:26 -0500 Randy Coleburn wrote: > Just want to let you know that the folks hosting the mail list service are trying to fulfill your request to be added to the m3devel mail list. > > The problem seems to be blacklisting of one of the hosts. At first it seemed your email address was blacklisted, but upon further investigation it seems your email server (scc-mailrelay.att.net) has blacklisted the mail list server at elegosoft. Note that the elegosoft server is based in Germany. > > The server admins are working on the problem, but not sure if/when it will be resolved. > > I'm one of the developers and also subscribe to the list and noticed the traffic about your request, so thought I would try and send you an email to see if it gets thru and to let you know of the problem. > > Regards, > Randy > Thanks for the heads up. I'll give them a call to see what the problem is. AT&T actually does it's mail hosting through Yahoo mail, so they might actually be the ones doing the blacklisting. I'm going to do some poking around on this end; and I'll send you an email if I find anything noteworthy. Thank you. -- Chris -----Original Message----- From: John Polstra [mailto:jdp at polstra.com] Sent: Monday, January 11, 2010 11:44 PM To: Tony Hosking Cc: m3devel at elegosoft.com Subject: Re: [M3devel] Fwd: CM3 development Inquiry. I forwarded this to him, and my mail log says it was delivered. John Tony Hosking wrote: > Actually, that diagnostic indicates that scc-mailrelay.att.net > is blocking messages from the Elegosoft > mail server (it is blacklisted!). > > Antony Hosking | Associate Professor | Computer Science | Purdue University > 305 N. University Street | West Lafayette | IN 47907 | USA > Office +1 765 494 6001 | Mobile +1 765 427 5484 > > > > > On 11 Jan 2010, at 05:52, Olaf Wagner wrote: > >> Quoting Tony Hosking > >: >> >>> This guy is trying to subscribe to m3devel. Can someone help him? >>> >>> Begin forwarded message: >>> >>>> From: Chris > >>>> Date: 10 January 2010 16:43:32 EST >>>> To: Tony Hosking > >>>> Subject: Re: CM3 development Inquiry. >>>> >>>> On Fri, 8 Jan 2010 13:01:21 -0500 >>>> Tony Hosking > >>>> wrote: >>>> >>>>> Did you manage to subscribe? >>>> >>>> I put in another subscription request just after your previous >>>> reply, and I'm still waiting. I wonder if the confirmation e-mail >>>> is getting through. Nonetheless, I'll keep trying. >> >> Unfortunately the address does not work: >> >> This is the mail system at host mx0.elegosoft.com >> . >> >> I'm sorry to have to inform you that your message could not >> be delivered to one or more recipients. It's attached below. >> >> For further assistance, please send mail to postmaster. >> >> If you do so, please include this problem report. You can >> delete your own text from the attached returned message. >> >> The mail system >> >> >: host >> scc-mailrelay.att.net[204.127.208.75] said: >> 521-88.198.54.133 blocked by sbc:blacklist.mailrelay.att.net. 521 >> DNSRBL: >> Blocked for abuse. See http://att.net/blocks (in reply to MAIL FROM >> command) >> >> If he really wants to join, he needs another mail address, but I cannot >> tell him that. >> >> Olaf >> -- >> Olaf Wagner -- elego Software Solutions GmbH >> Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany >> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 >> 86 95 >> http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin >> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: >> DE163214194 >> > From rcolebur at SCIRES.COM Tue Jan 12 06:18:51 2010 From: rcolebur at SCIRES.COM (Randy Coleburn) Date: Tue, 12 Jan 2010 00:18:51 -0500 Subject: [M3devel] FloatMode In-Reply-To: References: , <420956.32527.qm@web23605.mail.ird.yahoo.com> , <770FAFA3-9F41-48F4-A2E0-D4CD947EE6D2@cs.purdue.edu> Message-ID: Jay, I think the documented intent in Modula-3 is that the programmer should write his code under the premise that any operation that could produce an overflow should be rewritten so as to avoid that problem. Further, that the implementation may or may not actually check for this condition, but to rely on it working a certain way (e.g., silent wrap) would be wrong. Further, if FloatMode were implemented, it would be possible to force the overflow check on. This situation does not prohibit a programmer from writing something that could produce overflow, and the fact that on some implementations overflow is not checked is considered ok for performance reasons. It is just that if the programmer were to rely on silent wrap, this reliance is NOT supported by the language and at some point will probably cause a checked runtime error. Indeed, folks often turn on extra checking during program testing to find as many programming faults as possible, then turn off the extra checking for production/delivery code to gain performance. So Modula-3 as a language supports this concept, though not all implementations may provide the ability to turn certain checks on or off. I agree that lumping the integer overflow control into an interface named "FloatMode" makes it a bit hard to find since "FloatMode" would make one think that the interface deals only with floating point. So, in Modula-3 a good programmer will add appropriate logic to prevent overflow by explicitly coding wrap-around or using some other method appropriate to the task at hand. A sloppy programmer won't care and his code will eventually break. See the comments about long-lived readers/writers for an example. Regards, Randy From: jayk123 at hotmail.com [mailto:jayk123 at hotmail.com] On Behalf Of Jay K Sent: Monday, January 11, 2010 11:55 PM To: Tony; m3devel Subject: [M3devel] FloatMode I thought FloatMode was only related to floating point. So I looked: "IntOverflow" = an integer operation produced a result whose absolute value is too large to be represented. "IntDivByZero" = integer "DIV" or "MOD" by zero. \end{quote} This part of it should be easy to implement for all architectures. The entire thing probably isn't too difficult either on many platforms either. However...I was surprised by this. I thought the real "intent" in Modula-3 to not have this be configurable and endeavor for overflow and divide by zero to always immediately raise an exception? The only "out" is that it might not get implemented on some platforms for some reason? For the floating point stuff: Probably like other per-platform code, this should be done in #ifdefed C. http://msdn.microsoft.com/en-us/library/e9b52ceh(VS.80).aspx http://kernel.org/doc/man-pages/online/pages/man3/fetestexcept.3.html etc. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Tue Jan 12 06:32:35 2010 From: jay.krell at cornell.edu (Jay K) Date: Tue, 12 Jan 2010 05:32:35 +0000 Subject: [M3devel] FloatMode In-Reply-To: References: , , <420956.32527.qm@web23605.mail.ird.yahoo.com>, , , <770FAFA3-9F41-48F4-A2E0-D4CD947EE6D2@cs.purdue.edu>, , Message-ID: Rewrite code to avoid overflow? That seems..difficult. Write it in a typical normal straightfoward fashion and rely on overflow checking to avoid bugs, imho. I think relying on silent wrap is bad but relying on overflow checks is appropriate. Really what I think is you need multiple types or interfaces. So that you can request silent wraparound for certain code and overflow checking for other code. It's not a per-thread setting, but a type thing. It is more "statically bound" than a runtime per thread setting. In the absence of this profusion of types though, a good safe compromise is the INTEGER/Word split. INTEGER is signed and should check overflow. Word is unsigned and silently wraps. Really this isn't everything. You also want unsigned with overflow checks, maybe signed with silent wraparound. Maybe the arithmetic library provides all this. I need to check. Testing your code one way and shipping it another way is a bad recipe. The checks need to be preserved in the shipping version because testing is never complete. Also because the checks might have unintended side effects. Ship what you test. Again though, isn't silent wraparound a safety hole? Or maybe not, maybe given that we have array bounds checking, maybe safety is preserved? (You know, what would happen incorrectly when positive + positive yields negative?) - Jay From: rcolebur at SCIRES.COM To: m3devel at elegosoft.com Date: Tue, 12 Jan 2010 00:18:51 -0500 Subject: Re: [M3devel] FloatMode Jay, I think the documented intent in Modula-3 is that the programmer should write his code under the premise that any operation that could produce an overflow should be rewritten so as to avoid that problem. Further, that the implementation may or may not actually check for this condition, but to rely on it working a certain way (e.g., silent wrap) would be wrong. Further, if FloatMode were implemented, it would be possible to force the overflow check on. This situation does not prohibit a programmer from writing something that could produce overflow, and the fact that on some implementations overflow is not checked is considered ok for performance reasons. It is just that if the programmer were to rely on silent wrap, this reliance is NOT supported by the language and at some point will probably cause a checked runtime error. Indeed, folks often turn on extra checking during program testing to find as many programming faults as possible, then turn off the extra checking for production/delivery code to gain performance. So Modula-3 as a language supports this concept, though not all implementations may provide the ability to turn certain checks on or off. I agree that lumping the integer overflow control into an interface named ?FloatMode? makes it a bit hard to find since ?FloatMode? would make one think that the interface deals only with floating point. So, in Modula-3 a good programmer will add appropriate logic to prevent overflow by explicitly coding wrap-around or using some other method appropriate to the task at hand. A sloppy programmer won?t care and his code will eventually break. See the comments about long-lived readers/writers for an example. Regards, Randy From: jayk123 at hotmail.com [mailto:jayk123 at hotmail.com] On Behalf Of Jay K Sent: Monday, January 11, 2010 11:55 PM To: Tony; m3devel Subject: [M3devel] FloatMode I thought FloatMode was only related to floating point. So I looked: "IntOverflow" = an integer operation produced a result whose absolute value is too large to be represented. "IntDivByZero" = integer "DIV" or "MOD" by zero. \end{quote} This part of it should be easy to implement for all architectures. The entire thing probably isn't too difficult either on many platforms either. However...I was surprised by this. I thought the real "intent" in Modula-3 to not have this be configurable and endeavor for overflow and divide by zero to always immediately raise an exception? The only "out" is that it might not get implemented on some platforms for some reason? For the floating point stuff: Probably like other per-platform code, this should be done in #ifdefed C. http://msdn.microsoft.com/en-us/library/e9b52ceh(VS.80).aspx http://kernel.org/doc/man-pages/online/pages/man3/fetestexcept.3.html etc. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From mika at async.async.caltech.edu Tue Jan 12 06:46:03 2010 From: mika at async.async.caltech.edu (Mika Nystrom) Date: Mon, 11 Jan 2010 21:46:03 -0800 Subject: [M3devel] Integer literals In-Reply-To: References: <14BF9CAD-8DCD-4D65-8928-88329D12D2F6@cs.purdue.edu>, <4B4BC627.6030103@lcwb.coop> Message-ID: <20100112054603.A07EA1A2078@async.async.caltech.edu> Jay K writes: > >>> One thing I've really struggled with over the introduction of LONGINT is >>> the need for distinct literal forms. This strikes me as odd=2C since >>> literals are really just ways of writing values=2C rather than stating >>> anything about how they should be represented. >>> (Yes=2C I know that the REAL/LONGREAL/EXTENDED literals are all distinct= >=2C >>> but they really do have incompatible value representations). >> >> I agree=2C the need for distinctly typed literals is much greater for the >> floating types than the integer types=2C because they can't be viewed >> as having overlapping value sets in any reasonable way. > >=20 >Huh? This seems to me to be directly opposite of the truth. >LONGREAL is a strict superset of REAL in what it can represent. >There is *complete* overlap. >Am I really mistaken here? >Floating point is indeed very wierd=2C but it isn't this wierd. >Right? >=20 >=20 > - Jay Jay, I think if you have hardware that's strictly compliant with IEEE 754, you're right. Or at least there exists an interpretation of the values that have this property. I alluded earlier to the fact that Alpha represents single-precision by zeroing out the middle of the double-precision register (some of the mantissa and some of the exponent). However I'm sure there are systems for which this is not true. Is Modula-3 forbidden from being ported to such machines? Mika From mika at async.async.caltech.edu Tue Jan 12 06:47:25 2010 From: mika at async.async.caltech.edu (Mika Nystrom) Date: Mon, 11 Jan 2010 21:47:25 -0800 Subject: [M3devel] Mixed arithmetic In-Reply-To: References: <4B4BBFE6.1090701@lcwb.coop> Message-ID: <20100112054725.2C8ED1A207C@async.async.caltech.edu> Jay K writes: > >> rather than having things >> happen behind the scenes=2C without the programmer's coding them >=20 >=20 >Just a reminder that things happen behind the scenes *all the time*. >It is the norm=2C not the exception. >Look at what "try" does. > It is two or three function calls. >Look at the garbage collector.=20 >Look at layering in various places. These things are not visible to the programmer. Mika From mika at async.async.caltech.edu Tue Jan 12 06:53:49 2010 From: mika at async.async.caltech.edu (Mika Nystrom) Date: Mon, 11 Jan 2010 21:53:49 -0800 Subject: [M3devel] 64bit file sizes now? In-Reply-To: References: , <185464DB-5CA9-4D5B-BCF7-9F7048D9FA05@cs.purdue.edu> Message-ID: <20100112055349.CBEFE1A2080@async.async.caltech.edu> Why not change the implementation to something using LONGINT (or BigInteger.T...) and then provide the old ones as a thin veneer over the new implementation, marking the old ones as <*OBSOLETE*>... Mika Jay K writes: >--_7e4b65ed-7d03-496f-8734-2648c7e5ee94_ >Content-Type: text/plain; charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable > > >Large files (64bit file sizes) are very old. > >Windows 95 had them in the released API 14+ years ago (1995)=2C NT a few ye= >ars before that (1993?)=2C betas earlier. I heard VMS had 64bit file sizes = >but I haven't confirmed. > >=20 > > > If the use-case is typically INTEGER then perhaps we > > need to think of alternatives using abstraction? >=20 > >Hm. StatusLong=2C SeekLong=2C IndexLong=2C LengthLong? > >Default calls Seek/Index/Length=2C range checked truncation? > >Kind of an annoying duplicity of APIs though. > >=20 > > - Jay >=20 > > >From: hosking at cs.purdue.edu >Date: Mon=2C 11 Jan 2010 22:10:06 -0500 >To: jay.krell at cornell.edu >CC: m3devel at elegosoft.com >Subject: Re: [M3devel] 64bit file sizes now? > > > > >On 11 Jan 2010=2C at 22:02=2C Jay K wrote: > > >So.. LONGINT as I understand will remain roughly as it was=2C except VAL(ex= >pr=2C INTEGER) is how you convert expr to INTEGER=2C instead of ORD(expire)= >. > > > >That's what I think makes most sense. > > > And this is already in place. > > > >Yes=2C it's in place. > > > >? >=20 >So I should go ahead and update File.i3/Status/size and Rd/Wr/Index/Seek/Le= >ngth to all be LONGINT=2C "whatever the consequences"? The consequences are= > roughly the first diff I sent out=2C with the caveats that I used ORD() in= >stead of VAL(=2CINTEGER)=2C and a few packages were left to fix. It is mech= >anical and simple and predictable=2C just tedious and ugly. >Most Rd/Wr users are limited to INTEGER "sizes" anyway=2C but a few might g= >ain capacity. >Classic simple example is the mklib and libdump code=2C they read the entir= >e file into memory and then deal with that. > > > >If the use-case is typically INTEGER then perhaps we need to think of alter= >natives using abstraction? > > > I can send the diffs ahead of time=2C but there's really no choices left a= >s to what they'll look like=2C it is forced by the limited capability of LO= >NGINT. >Had they used LONGINT in the first place=2C of course=2C there'd be no diff= > at this time=2C the ugliness would have been builtin from the start. > >When they originally wrote it large file sizes were only proposed not imple= >mented. I don't think C even had long long then. (Yes=2C I am showing my = >age! -- we are talking almost 20 years ago now!) If they had used LONGINT = >from the start then folks would have not had any ugliness because all would= > have used LONGINT. Now=2C to save some hassles in future=2C perhaps we = >need a better abstraction! Let's ponder that before you propagate your cha= >nges. > > = > >--_7e4b65ed-7d03-496f-8734-2648c7e5ee94_ >Content-Type: text/html; charset="iso-8859-1" >Content-Transfer-Encoding: quoted-printable > > > > > > >Large files (64bit file sizes) are very old.
>Windows 95 had them in the released =3BAPI 14+ years ago (1995)=2C NT a= > few years before that (1993?)=2C betas earlier. I heard VMS had 64bit file= > sizes but I haven't confirmed.
> =3B
>
 =3B>=3B If the use-case is typically INTEGER then perhaps weIV> >
 =3B>=3B need to think of alternatives using abstraction?
> =3B
>Hm. StatusLong=2C SeekLong=2C IndexLong=2C LengthLong?
>Default calls Seek/Index/Length=2C range checked truncation?
>Kind of an annoying duplicity of APIs though.
> =3B
> =3B- Jay
 =3B
>
>From: hosking at cs.purdue.edu
Date: Mon=2C 11 Jan 2010 22:10:06 -0500
T= >o: jay.krell at cornell.edu
CC: m3devel at elegosoft.com
Subject: Re: [M3de= >vel] 64bit file sizes now?

>
APSE: separate=3B FONT: 12px Helvetica=3B WHITE-SPACE: normal=3B LETTER-SPA= >CING: normal=3B COLOR: rgb(0=2C0=2C0)=3B WORD-SPACING: 0px" class=3DecxAppl= >e-style-span>DER-COLLAPSE: separate=3B FONT: 12px Helvetica=3B WHITE-SPACE: normal=3B LE= >TTER-SPACING: normal=3B COLOR: rgb(0=2C0=2C0)=3B WORD-SPACING: 0px" class= >=3DecxApple-style-span> >
TEXT-INDENT: 0px=3B BORDER-COLLAPSE: separate=3B FONT: 12px Helvetica=3B W= >HITE-SPACE: normal=3B LETTER-SPACING: normal=3B COLOR: rgb(0=2C0=2C0)=3B WO= >RD-SPACING: 0px" class=3DecxApple-style-span> none=3B TEXT-INDENT: 0px=3B BORDER-COLLAPSE: separate=3B FONT: 12px Helvet= >ica=3B WHITE-SPACE: normal=3B LETTER-SPACING: normal=3B COLOR: rgb(0=2C0=2C= >0)=3B WORD-SPACING: 0px" class=3DecxApple-style-span>ANSFORM: none=3B TEXT-INDENT: 0px=3B BORDER-COLLAPSE: separate=3B FONT: 12p= >x Helvetica=3B WHITE-SPACE: normal=3B LETTER-SPACING: normal=3B COLOR: rgb(= >0=2C0=2C0)=3B WORD-SPACING: 0px" class=3DecxApple-style-span>"TEXT-TRANSFORM: none=3B TEXT-INDENT: 0px=3B BORDER-COLLAPSE: separate=3B F= >ONT: 12px Helvetica=3B WHITE-SPACE: normal=3B LETTER-SPACING: normal=3B COL= >OR: rgb(0=2C0=2C0)=3B WORD-SPACING: 0px" class=3DecxApple-style-span>style=3D"TEXT-TRANSFORM: none=3B TEXT-INDENT: 0px=3B BORDER-COLLAPSE: separ= >ate=3B FONT: 12px Helvetica=3B WHITE-SPACE: normal=3B LETTER-SPACING: norma= >l=3B COLOR: rgb(0=2C0=2C0)=3B WORD-SPACING: 0px" class=3DecxApple-style-spa= >n>E: separate=3B FONT: 12px Helvetica=3B WHITE-SPACE: normal=3B LETTER-SPACIN= >G: normal=3B COLOR: rgb(0=2C0=2C0)=3B WORD-SPACING: 0px" class=3DecxApple-s= >tyle-span>-COLLAPSE: separate=3B FONT: 12px Helvetica=3B WHITE-SPACE: normal=3B LETTE= >R-SPACING: normal=3B COLOR: rgb(0=2C0=2C0)=3B WORD-SPACING: 0px" class=3Dec= >xApple-style-span>=3B BORDER-COLLAPSE: separate=3B FONT: 12px Helvetica=3B WHITE-SPACE: norma= >l=3B LETTER-SPACING: normal=3B COLOR: rgb(0=2C0=2C0)=3B WORD-SPACING: 0px" = >class=3DecxApple-style-span> >
On 11 Ja= >n 2010=2C at 22:02=2C Jay K wrote:
= >
>

>
ER-COLLAPSE: separate=3B FONT: medium Helvetica=3B WHITE-SPACE: normal=3B L= >ETTER-SPACING: normal=3B WORD-SPACING: 0px" class=3DecxApple-style-span> >
>So.. LONGINT as I understand will remain roughly as it was=2C except VAL(e= >xpr=2C INTEGER) is how you convert expr to INTEGER=2C instead of ORD(expire= >).
>

>
That's what I think makes most sense.

>
ER-COLLAPSE: separate=3B FONT: medium Helvetica=3B WHITE-SPACE: normal=3B L= >ETTER-SPACING: normal=3B WORD-SPACING: 0px" class=3DecxApple-style-span> >
> =3BAnd this is already in place.
>

>
Yes=2C it's in place.
>

>
ER-COLLAPSE: separate=3B FONT: medium Helvetica=3B WHITE-SPACE: normal=3B L= >ETTER-SPACING: normal=3B WORD-SPACING: 0px" class=3DecxApple-style-span> >
>?
 =3B
So I should go ahead and update File.i3/Status/size and R= >d/Wr/Index/Seek/Length to all be LONGINT=2C "whatever the consequences"? Th= >e consequences are roughly the first diff I sent out=2C with the caveats th= >at I used ORD() instead of VAL(=2CINTEGER)=2C and a few packages were left = >to fix. It is mechanical and simple and predictable=2C just tedious and ugl= >y.
Most Rd/Wr users are limited to INTEGER "sizes" anyway=2C but a few m= >ight gain capacity.
Classic simple example is the mklib and libdump code= >=2C they read the entire file into memory and then deal with that.
>
>

>
If the use-case is typically INTEGER then perhaps we need to think of = >alternatives using abstraction?

>
ER-COLLAPSE: separate=3B FONT: medium Helvetica=3B WHITE-SPACE: normal=3B L= >ETTER-SPACING: normal=3B WORD-SPACING: 0px" class=3DecxApple-style-span> >
> =3BI can send the diffs ahead of time=2C but there's really no choice= >s left as to what they'll look like=2C it is forced by the limited capabili= >ty of LONGINT.
Had they used LONGINT in the first place=2C of course=2C = >there'd be no diff at this time=2C the ugliness would have been builtin fro= >m the start.

>
When they originally wrote it large file sizes were only proposed not = >implemented.  =3BI don't think C even had span fa