[M3devel] small objects

Tony Hosking hosking at cs.purdue.edu
Tue Apr 7 04:52:59 CEST 2009


On 7 Apr 2009, at 12:27, Randy Coleburn wrote:

> Hey, will this proposal mean that packages like "stable" and  
> "stubgen" need to be changed also, in addition to both versions of  
> pickles?

They build on m3tk so should just work, modulo any builtin typecode  
information.  TAGGED INTEGER will have a predefined typecode just like  
NULL.

>  What about any package that deals with parsing of M3 code, e.g.  
> pretty-printers, CM3IDE, etc.?

Same.  To that end, how do those cope with LONGINT right now?  I did  
push the changes for LONGINT into m3tk.

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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20090407/50d49c10/attachment-0002.html>


More information about the M3devel mailing list