<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-15">
<META content="MSHTML 6.00.6000.16809" name=GENERATOR></HEAD>
<BODY 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> </DIV>
<DIV>What about any package that deals with parsing of M3 code, e.g. pretty-printers, CM3IDE, etc.?</DIV>
<DIV> </DIV>
<DIV>Regards,</DIV>
<DIV>Randy<BR><BR>>>> Tony Hosking <hosking@cs.purdue.edu> 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></BODY></HTML>