<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div apple-content-edited="true"><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div>On 7 Apr 2009, at 12:27, Randy Coleburn wrote:</div></span></span></span></span></span></span></span></span></div></span></div><div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="MARGIN: 4px 4px 1px"> <div>Hey, will this proposal mean that packages like "stable" and "stubgen" need to be changed also, in addition to both versions of pickles?</div></div></blockquote><div><br></div><div>They build on m3tk so should just work, modulo any builtin typecode information.  TAGGED INTEGER will have a predefined typecode just like NULL.</div><br><blockquote type="cite"><div style="MARGIN: 4px 4px 1px"> <div> <span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">What about any package that deals with parsing of M3 code, e.g. pretty-printers, CM3IDE, etc.?</span></div></div></blockquote><div><br></div><div>Same.  To that end, how do those cope with LONGINT right now?  I did push the changes for LONGINT into m3tk.</div><br><blockquote type="cite"><div style="MARGIN: 4px 4px 1px"> <div> <span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">Regards,</span></div> <div>Randy<br><br>>>> Tony Hosking <<a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a>> 4/6/2009 10:16 PM >>><br>On 7 Apr 2009, at 10:42, Mika Nystrom wrote:<br><br>> You mean this proposal (you had two, I think)?<br><br>Yes, this is the proposal I converged on.  It really is only minimal  <br>change to the type system: introduction of a third hierarchy of   <br>TAGGED reference types.  I did something similar for orthogonal  <br>persistence a few years ago where it was useful to have a TRANSIENT  <br>reference hierarchy for things that should not persist.  [The  <br>semantics was that every run of a program would initialize TRANSIENT  <br>references to NIL rather than have them have the persistent value.   <br>This was slightly messier in that I also permitted TRANSIENT REFANY <:  <br>REFANY, which was a little odd.]<br><br>> --<br>><br>> NULL <: REF T <: REFANY<br>> NULL <: UNTRACED REF T <: ADDRESS<br>> TAGGED INTEGER <: TAGGED REF T <: TAGGED REFANY<br>><br>> Note that NULL is not a subtype of TAGGED REF T or TAGGED REFANY.<br>><br>> ROOT <: REFANY<br>> TAGGED ROOT <: TAGGED REFANY<br>> NULL <: T OBJECT END <: T where T <: REFANY or T <: ADDRESS<br>> TAGGED INTEGER <: T OBJECT ... END <: T where T <: TAGGED REFANY<br>><br>> Note that NULL is not a subtype of T OBJECT ... END where T <: TAGGED<br>> REFANY.<br>><br>> ---<br>><br>> I like it fine, I think... I'm just worried, generally, about<br>> changing the type system.  Hmmmm... you mean that the TAGGED<br>> things would just be a separate hierarchy?<br><br>The change is relatively minor in that it doesn't touch the original  <br>REFANY hierarchy.<br><br>> So you'd just add TAGGED in front of the REFs for this new hierarchy.<br>> But why no NULL?<br><br>No NULL because then we need a test for both NIL and values of type  <br>TAGGED INTEGER on every dereference.  You can easily declare:<br><br>TYPE Null = TAGGED INTEGER;<br>CONST Nil = VAL(0, TAGGED INTEGER);<br><br>The point is that TAGGED INTEGER now lets you have a range of non- <br>pointer reference values, whereas NIL is the singleton non-reference  <br>value in type NULL.<br><br>> And you're comfortable with doing the conversions automatically?<br><br>No, I said that the conversions needed to be explicit<br><br>><br>> So<br>><br>>  tx : TAGGED INTEGER := 5;<br><br>tx: TAGGED INTEGER := VAL(5,TAGGED INTEGER);<br><br>>  x  : INTEGER := tx;<br><br>x: INTEGER := ORD(tx);<br><br>> would be OK?<br>><br>> In that case it's just the m3tk that needs to be modified, and<br>> that's just busy work, I think.  If it works it's beautiful...<br><br>As I said, I am almost done with the compiler changes, and only need  <br>to push it into the run-time.  Things like m3tk and pickles will need  <br>to be smartened up as necessary.<br><br>><br>><br>>     Mika<br>><br>><br>><br>> Tony Hosking writes:<br>>> I really don't like your proposal for the reasons you mention.  It<br>>> makes regular REF more expensive than it currently is.  What is it<br>>> about my relatively minor changes to the type system that you object<br>>> to?  I've just about finished changing the compiler front-end (in<br>>> relatively minor ways) to accomodate the proposal I made yesterday.<br>>> And it has the advantage of separating REF from TAGGED REF so we keep<br>>> the standard REF clean.<br>>><br>>> On 7 Apr 2009, at 00:50, Mika Nystrom wrote:<br>>><br>>>> Hi Rodney,<br>>>><br>>>> I would like this capability too, but I am a bit wary of Tony's<br>>>> idea of changing the Modula-3 language---even in a "minor" way.<br>>>> I've been working for the last week or so on an application using<br>>>> the Modula-3 Toolkit, and I must say I have realized that the<br>>> Modula-3 type system has a lot more subtleties than I thought.  I<br>>>> would not want to make any real changes to it.  There's a paper<br>>>> called "The Modula-3 Type System" by Cardelli, Donahue, Kalsow, and<br>>>> Nelson that is worth studying in detail before making any changes<br>>>> whatsoever, I think.  Also remember that changes to the type system<br>>>> will affect m3tk and anything that depends on m3tk (which includes<br>>>> two or three stub generators in the main tree and who knows how<br>>>> many dependencies outside of it).<br>>>><br>>>> I'm still not sure why we can't take the approach of Word.T .<br>>>> Make a RefanyOrInt.T that can safely be:<br>>>><br>>>> 1. Tested whether it is a small integer or a REFANY<br>>>><br>>>> 2. If a REFANY, be dereferenced as normal, *or* via<br>>>>  RefanyOrInt.ToRefany<br>>>><br>>>> 3. If a small integer, can be extracted via RefanyOrInt.ToInt<br>>>><br>>>> 4. Created either as a small integer or a REFANY<br>>>><br>>>> Any other operations on it (including ISTYPE and TYPECASE, at least<br>>>> when the object is a small integer) would result in a checked  <br>>>> runtime<br>>>> error.<br>>>><br>>>> Note that with the declaration "RefanyOrInt.T = REFANY", the current<br>>>> compiler will as far as I know not accept any operations on<br>>>> RefanyOrInt.T outside of ISTYPE, TYPECASE, and NARROW (explicit or<br>>>> implicit).<br>>>><br>>>> I wouldn't be surprised if most of what I'm proposing already works<br>>>> (i.e., crashes with a checked runtime error as it should) with the<br>>>> current runtime.  Anything that slips through would need to be fixed<br>>>> up with a one-bit check of the LSB of the REFANY for the operations<br>>>> mentioned above.  Unfortunately this has to be done for operations  <br>>>> on<br>>>> every REFANY, not just the new type.<br>>>><br>>>> I think that Modula-3 programmers are already aware that using<br>>>> REFANYs involves forcing the runtime to do extra type-checking work,<br>>>> so they already know not to use them if they are looking for maximum<br>>>> performance, so I don't think that burdening operations on REFANY<br>>>> with an extra one-bit check is too onerous.<br>>>><br>>>> An advantage of my proposal is that the amount of code in the new<br>>>> proposed library is truly diminutive.  In fact, I think I posted<br>>>> pretty much that code to the list a few weeks ago.<br>>>><br>>>> (If you missed it, it's<br>>>><br>>>> <a href="http://www.async.caltech.edu/~mika/interp/">http://www.async.caltech.edu/~mika/interp/</a><br>>>><br>>>> )<br>>>><br>>>>    Mika<br>>>><br>>>><br>>>> "Rodney M. Bates" writes:<br>>>>> I spent quite a bit of time playing with a more general system  <br>>>>> where<br>>>>> there is a set of "tagged" types, with (an implementation-defined<br>>>>> subrange of) INTEGER and a reference type both being a subtype of a<br>>>>> tagged type.  It might have been tolerable, if it weren't for the<br>>>>> interaction with object subtypes and opaque types, which quickly<br>>>>> gets deep into a deep linguistic tar pit.<br>>>>><br>>>>> Tony's approach is much simpler and would serve what I see as the<br>>>>> need.  It does sacrifice any static checking of what reference type<br>>>>> is being tagged, and will also require an extra runtime ISTYPE/<br>>>>> TYPECASE.<br>>>>><br>>>>> Would INTEGER and REFANY be assignable to TAGGED, or would there<br>>>>> also need to be an explicit conversion in that direction too, say<br>>>>> VAL(x, TAGGED)?  I think I favor the explicit conversion here.  It<br>>>>> is a bit inconsistent with the usual Modula-3 assignability<br>>>>> philosophy,<br>>>>> but not requiring the explicit conversion already gets your toes<br>>>>> into tar.<br>>>>><br>>>>> We would have to have something more like ISTYPE, though, which  <br>>>>> will<br>>>>> tell which type the value belongs to without risking a runtime  <br>>>>> error,<br>>>>> which VAL would do.<br>>>>><br>>>>> An intermediate approach might be to have a set of tagged types<br>>>>> constructed by, say, TAGGED T, where I is a reference type, but<br>>>>> with no subtype relations on them at all, thus still requiring<br>>>>> the explicit conversions and checks.<br>>>>><br>>>>> I do want to say, I _really_ want this capability somehow.  I have<br>>>>> an ADT module whose internal data structure, for full generality,<br>>>>> needs to have two heap objects (the second because it has nonstatic<br>>>>> size) and 11 total words counting the orginal pointer, in the  <br>>>>> case of<br>>>>> values that would fit directly  into the "pointer" word.  Moreover,<br>>>>> these small cases are in the great majority.<br>>>>><br>>>>> Besides the 11-to-one increase in actual occupied space, there<br>>>>> is extra time for allocation, periodic tracing, and collection,  <br>>>>> space<br>>>>> loss due to heap fragmentation, and time/space tradeoff loss due to<br>>>>> reduced locality of reference.  So sometimes, it would be a big<br>>>>> performance gain if we could do it.<br>>>>><br>>>>><br>>>>> Tony Hosking wrote:<br>>>>> It is a much more pervasive hack than I would be comfortable with<br>>>>>> since it touches on the compiler (for all the type operations) as<br>>>>>> well<br>>>>>> as the run-time system in ways that are pretty gross.  I would  <br>>>>>> much<br>>>>>> rather have a new TAGGED builtin.  ISTYPE would not work on it  <br>>>>>> since<br>>>>>> that only works on references.  The only thing you need is a way  <br>>>>>> to<br>>>>>> extract the value -- we could overload VAL(x, T) where x can be a<br>>>>>> TAGGED and T can be REFANY or INTEGER.<br>>>>>><br>>>>>><br><br><br></div></div></blockquote></div><br></body></html>