From dragisha at m3w.org Sat Mar 1 19:12:36 2014 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sat, 1 Mar 2014 19:12:36 +0100 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> Message-ID: I am not following this thread so well, but? Why do you need something like this? Maybe to use it as an argument to a C callback? On 28 Feb 2014, at 18:40, JC Chu wrote: >> ... The above technique works if you really want to simulate keying on the address (as it would be in a no-move GC environment.), which I suppose is what you wanted. > > Yes, I was indeed in need of an immutable version of REFANY. > > ? JC Chu > > -----Original Message----- > From: Rodney M. Bates [mailto:rodney_bates at lcwb.coop] > Sent: Friday, February 28, 2014 23:16 > To: m3devel at elegosoft.com > Subject: Re: [M3devel] REFANY-keyed tables? > > > > On 02/26/2014 09:28 PM, Rodney M. Bates wrote: >> >> >> On 02/26/2014 11:08 AM, JC Chu wrote: >>> Hi, >>> >>> I need a REFANY-to-INTEGER table in my program but RefIntTbl.Default is giving me runtime errors. Apparently Table(Key, Value) uses Key.Equal() and Key.Hash(), but those procedures in Refany, which is use to instantiate RefIntTbl, both raise a fatal exception. >>> >> >> The garbage collector is a (partially) compacting collector, which >> means it can move a heap object and adjust all the pointers to it, if >> it knows where they all are, which holds for some objects. So the bit >> contents of a REFANY can change. This means it is not possible to have a consistent Hash on the pointer value alone. >> >> So Refany.Hash is deliberately coded to raise this exception, to >> prevent a far more insidious bug. >> >>> I?m a bit confused since a number of REFANY-keyed tables are shipped with CM3. Is this actually the expected behavior or am I doing anything wrong? >>> >> >> Hmm, can you point out where these are? >> >> I have some pointer-keyed tables, but they use techniques like giving >> every object an object sequence number field, explicitly initialized >> when an object is allocated, and using that for the Hash function. >> But this won't work for REFANY, because it can have no fields. >> > > There is more to this. The above technique works if you really want to simulate keying on the address (as it would be in a no-move GC environment.), which I suppose is what you wanted. > > But in many cases, you might want to hash on the contents, not the address of the object, in which case, the technique used in juno-2, using actual data fields instead of an object sequence number is the right way. For example, to turn the objects into atoms. > >> So the table can only work on a narrower set of allocated object types than REFANY. >> If you need the table to hold addresses of a mixture of different >> types, you can still do that with a hierarchy of OBJECT types, but >> they will have to have a common supertype that contains whatever fields the Hash function needs for consistency. >> >> It would be possible that pointers get passed around in REFANY-typed >> (statically) variables, but it is carefully arranged that they all >> have an allocated type that has fields a Hash function can work on. >> Hash would then have to do a NARROW or TYPECASE to the type it expected. >> >> Rodney Bates >> >>> Thanks. >>> >>> ? JC Chu >>> >> >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From jcchu at acm.org Sun Mar 2 06:09:48 2014 From: jcchu at acm.org (JC Chu) Date: Sun, 2 Mar 2014 13:09:48 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , Message-ID: Oh I just needed to count the number of times each object has been visited, where objects a and b are considered identical iff Refany.Equal(a, b), so tagging objects with sequential integers and using instead an INTEGER-to-INTEGER table sufficed. - JC Chu ---------------------------------------- > Subject: Re: [M3devel] REFANY-keyed tables? > From: dragisha at m3w.org > Date: Sat, 1 Mar 2014 19:12:36 +0100 > CC: rodney_bates at lcwb.coop; m3devel at elegosoft.com > To: jcchu at acm.org > > I am not following this thread so well, but. Why do you need something like this? Maybe to use it as an argument to a C callback? > From mika at async.caltech.edu Sun Mar 2 14:02:43 2014 From: mika at async.caltech.edu (mika at async.caltech.edu) Date: Sun, 02 Mar 2014 05:02:43 -0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , Message-ID: <20140302130243.7BD831A2095@async.async.caltech.edu> I just want to make an observation... REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of REFANY. If a, b : REFANY and a = b then a and b point to the same object. You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. (Not because the garbage collector is implemented one way or another.) Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. The rest is implementation... I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. It defeats the purpose of REFANY. If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilities are more limited than Java's, for mostly good reasons.) Mika From jcchu at acm.org Sun Mar 2 16:00:25 2014 From: jcchu at acm.org (JC Chu) Date: Sun, 2 Mar 2014 23:00:25 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <20140302130243.7BD831A2095@async.async.caltech.edu> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> Message-ID: > You can't apply ^ to REFANY. That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. 1. x, y: REF T, where T has an equivalence relation T.Equal. 2. Initially, x = y # NIL and st(x) = st(y) = s. 3. Then the GC creates a copy s' of s. 4. Then the GC updates x so that st(x) = s'. 5. But then y still has the old value: st(y) = s. At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, because it can only be based on Refany.Equal. (If T.Equal is used then we won?t have this problem.) > REFANY behaves the way the Green Book says it does. You mean Systems Programming with Modula-3? ? JC Chu -----Original Message----- From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] Sent: Sunday, March 2, 2014 21:03 To: JC Chu; rodney_bates at lcwb.coop Cc: m3devel at elegosoft.com Subject: Re: [M3devel] REFANY-keyed tables? I just want to make an observation... REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of REFANY. If a, b : REFANY and a = b then a and b point to the same object. You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. (Not because the garbage collector is implemented one way or another.) Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. The rest is implementation... I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. It defeats the purpose of REFANY. If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilities are more limited than Java's, for mostly good reasons.) Mika From rodney_bates at lcwb.coop Sun Mar 2 20:57:08 2014 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sun, 02 Mar 2014 13:57:08 -0600 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> Message-ID: <53138D14.2030102@lcwb.coop> On 03/02/2014 09:00 AM, JC Chu wrote: >> You can't apply ^ to REFANY. > > That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. > > 1. x, y: REF T, where T has an equivalence relation T.Equal. > 2. Initially, x = y # NIL and st(x) = st(y) = s. > 3. Then the GC creates a copy s' of s. > 4. Then the GC updates x so that st(x) = s'. > 5. But then y still has the old value: st(y) = s. With a correctly implemented GC (which we have), step 5 can't happen. The GC will prevent any use of y by a running mutator thread until it (the GC) has updated y as well as x, so x = y again. My questions to Tony were about how the M3 GC accomplishes this, and it does. The motivatation for not giving REFANY a succeeding Hash is that, after the updates, x = y # . This would make a hash table fail, even if x = y works as defined. Mika is right, as long as you stay in the safe subset of the language. You simply can't write a hash function on a REFANY at all. Somebody could, however, declare the module with the Hash function UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if the sizes were not the same), and return that or something derived from it. It is never feasible in any language to define everything that can happen, when type-unsafe techniques are used. That inevitably gets into implementation details, which we often make assumptions about rather cavalierly. Part of the wisdom of Modula-3 is that it clearly defines what the safe subset is, then equally clearly defines the semantics of that,, without getting into implementation. I was careless about glossing over the safe/unsafe distinction. > > At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, because it can only be based on Refany.Equal. (If T.Equal is used then we won?t have this problem.) > >> REFANY behaves the way the Green Book says it does. > > You mean Systems Programming with Modula-3? > > ? JC Chu > > -----Original Message----- > From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] > Sent: Sunday, March 2, 2014 21:03 > To: JC Chu; rodney_bates at lcwb.coop > Cc: m3devel at elegosoft.com > Subject: Re: [M3devel] REFANY-keyed tables? > > > I just want to make an observation... > > REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of REFANY. > > If a, b : REFANY and a = b then a and b point to the same object. > > You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. > (Not because the garbage collector is implemented one way or another.) > > Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. > > The rest is implementation... > > I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. > > I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. > It defeats the purpose of REFANY. > > If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilities are more limited than Java's, for mostly good reasons.) > > Mika > From mika at async.caltech.edu Sun Mar 2 21:17:41 2014 From: mika at async.caltech.edu (mika at async.caltech.edu) Date: Sun, 02 Mar 2014 12:17:41 -0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <53138D14.2030102@lcwb.coop> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop> Message-ID: <20140302201741.C42E71A2094@async.async.caltech.edu> Right, right. Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. The language specification does talk about memory, albeit abstractly. If x and y point to the same object and you don't assign to them, they keep pointing to the same object. That is the language semantics, and yes, by The Green Book I mean Systems Programming with Modula-3. And yeah whatever the implementation does has to respect the language semantics. If the GC wants to change the bit representation of x then it has to change the bit representation of y in a way such that your program will always see x = y. Note that it is NOT literally required that the bit representation of x always equals the bit representation of y. But I do believe the GC accomplishes x = y by ensuring that their bit representations are always equal in any state where they may be checked by your program. Another way of looking at this is to consider references in the language as products of NEW. Every reference to a particular evaluation of NEW always points to the same thing. If NEW has only been evaluated once in your program, there can only be two REFANYs: NIL and the result of that NEW. Those are the language semantics. And of course the implementation has to go to some effort to ensure this property holds even as it fiddles with the bit representations of the two REFANYs. (NIL's bit representation is *probably* constant, but it doesn't have to be...) Mika "Rodney M. Bates" writes: > > >On 03/02/2014 09:00 AM, JC Chu wrote: >>> You can't apply ^ to REFANY. >> >> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >> >> 1. x, y: REF T, where T has an equivalence relation T.Equal. >> 2. Initially, x = y # NIL and st(x) = st(y) = s. >> 3. Then the GC creates a copy s' of s. >> 4. Then the GC updates x so that st(x) = s'. >> 5. But then y still has the old value: st(y) = s. > >With a correctly implemented GC (which we have), step 5 can't happen. The GC >will prevent any use of y by a running mutator thread until it (the GC) has >updated y as well as x, so x = y again. My questions to Tony were about how the >M3 GC accomplishes this, and it does. > >The motivatation for not giving REFANY a succeeding Hash is that, after >the updates, x = y # . This would >make a hash table fail, even if x = y works as defined. Mika is right, >as long as you stay in the safe subset of the language. You simply can't >write a hash function on a REFANY at all. > >Somebody could, however, declare the module with the Hash function UNSAFE, >LOOPHOLE the REFANY value to a Word.T (or something else, if the sizes were >not the same), and return that or something derived from it. > >It is never feasible in any language to define everything that can happen, >when type-unsafe techniques are used. That inevitably gets into implementation >details, which we often make assumptions about rather cavalierly. Part of >the wisdom of Modula-3 is that it clearly defines what the safe subset is, >then equally clearly defines the semantics of that,, without getting into >implementation. > >I was careless about glossing over the safe/unsafe distinction. > >> >> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, > because it can only be based on Refany.Equal. (If T.Equal is used then we won???t have this problem.) >> >>> REFANY behaves the way the Green Book says it does. >> >> You mean Systems Programming with Modula-3? >> >> ??? JC Chu >> >> -----Original Message----- >> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >> Sent: Sunday, March 2, 2014 21:03 >> To: JC Chu; rodney_bates at lcwb.coop >> Cc: m3devel at elegosoft.com >> Subject: Re: [M3devel] REFANY-keyed tables? >> >> >> I just want to make an observation... >> >> REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of RE >FANY. >> >> If a, b : REFANY and a = b then a and b point to the same object. >> >> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >> (Not because the garbage collector is implemented one way or another.) >> >> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >> >> The rest is implementation... >> >> I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to > think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >> >> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >> It defeats the purpose of REFANY. >> >> If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures > for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilitie >s are more limited than Java's, for mostly good reasons.) >> >> Mika >> From jcchu at acm.org Mon Mar 3 14:25:42 2014 From: jcchu at acm.org (JC Chu) Date: Mon, 3 Mar 2014 21:25:42 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <20140302201741.C42E71A2094@async.async.caltech.edu> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop>, <20140302201741.C42E71A2094@async.async.caltech.edu> Message-ID: > Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). >>> 5. But then y still has the old value: st(y) = s. >> With a correctly implemented GC (which we have), step 5 can't happen. > If x and y point to the same object and you don't assign to them, they keep pointing to the same object. Hmm... I?ll glad this is the case, but I don?t see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? ? JC Chu ---------------------------------------- > To: jcchu at acm.org > CC: mika at async.caltech.edu; m3devel at elegosoft.com > To: rodney_bates at lcwb.coop > Subject: Re: [M3devel] REFANY-keyed tables? > Date: Sun, 2 Mar 2014 12:17:41 -0800 > From: mika at async.caltech.edu > > > Right, right. > > Another way of seeing it is that if st(x) = st(y) then x and y are > pointing to the same object. The language specification does talk about > memory, albeit abstractly. > > If x and y point to the same object and you don't assign to them, they > keep pointing to the same object. That is the language semantics, > and yes, by The Green Book I mean Systems Programming with Modula-3. > > And yeah whatever the implementation does has to respect the language > semantics. If the GC wants to change the bit representation of x then it > has to change the bit representation of y in a way such that your program > will always see x = y. Note that it is NOT literally required that the > bit representation of x always equals the bit representation of y. But > I do believe the GC accomplishes x = y by ensuring that their bit > representations are always equal in any state where they may be checked > by your program. > > Another way of looking at this is to consider references in the language > as products of NEW. Every reference to a particular evaluation of NEW > always points to the same thing. If NEW has only been evaluated once > in your program, there can only be two REFANYs: NIL and the result of > that NEW. Those are the language semantics. And of course the implementation > has to go to some effort to ensure this property holds even as it fiddles > with the bit representations of the two REFANYs. (NIL's bit representation > is *probably* constant, but it doesn't have to be...) > > Mika > > "Rodney M. Bates" writes: >> >> >>On 03/02/2014 09:00 AM, JC Chu wrote: >>>> You can't apply ^ to REFANY. >>> >>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>> >>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>> 3. Then the GC creates a copy s' of s. >>> 4. Then the GC updates x so that st(x) = s'. >>> 5. But then y still has the old value: st(y) = s. >> >>With a correctly implemented GC (which we have), step 5 can't happen. The GC >>will prevent any use of y by a running mutator thread until it (the GC) has >>updated y as well as x, so x = y again. My questions to Tony were about how the >>M3 GC accomplishes this, and it does. >> >>The motivatation for not giving REFANY a succeeding Hash is that, after >>the updates, x = y # . This would >>make a hash table fail, even if x = y works as defined. Mika is right, >>as long as you stay in the safe subset of the language. You simply can't >>write a hash function on a REFANY at all. >> >>Somebody could, however, declare the module with the Hash function UNSAFE, >>LOOPHOLE the REFANY value to a Word.T (or something else, if the sizes were >>not the same), and return that or something derived from it. >> >>It is never feasible in any language to define everything that can happen, >>when type-unsafe techniques are used. That inevitably gets into implementation >>details, which we often make assumptions about rather cavalierly. Part of >>the wisdom of Modula-3 is that it clearly defines what the safe subset is, >>then equally clearly defines the semantics of that,, without getting into >>implementation. >> >>I was careless about glossing over the safe/unsafe distinction. >> >>> >>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, >> because it can only be based on Refany.Equal. (If T.Equal is used then we won?t have this problem.) >>> >>>> REFANY behaves the way the Green Book says it does. >>> >>> You mean Systems Programming with Modula-3? >>> >>> ? JC Chu >>> >>> -----Original Message----- >>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>> Sent: Sunday, March 2, 2014 21:03 >>> To: JC Chu; rodney_bates at lcwb.coop >>> Cc: m3devel at elegosoft.com >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> >>> >>> I just want to make an observation... >>> >>> REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of RE >>FANY. >>> >>> If a, b : REFANY and a = b then a and b point to the same object. >>> >>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>> (Not because the garbage collector is implemented one way or another.) >>> >>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>> >>> The rest is implementation... >>> >>> I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to >> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>> >>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>> It defeats the purpose of REFANY. >>> >>> If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures >> for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilitie >>s are more limited than Java's, for mostly good reasons.) >>> >>> Mika >>> From rcolebur at SCIRES.COM Mon Mar 3 23:56:32 2014 From: rcolebur at SCIRES.COM (Coleburn, Randy) Date: Mon, 3 Mar 2014 22:56:32 +0000 Subject: [M3devel] REFANY-keyed tables? Message-ID: <0BB8FA59C2932741A3A2941A8B9D8BFF925EE54F@ATLEX04-SRV.SCIRES.LOCAL> JC: My understanding is that this is NOT an implementation-specific property, but rather it is a language property/requirement that all implementations must meet. *If* the implementation's GC were to move things around, it would have to update *all* references to point to the new location BEFORE allowing any thread to use the reference, thereby preventing incorrect use of the old location. So, if X and Y are references AND if X=Y (i.e. they reference the same thing), the implementation must ensure X=Y remains valid for all threads of execution even if the GC chooses to relocate the referents. For the CM3 implementation, Anthony Hosking has worked the GC "magic" to make sure the X=Y property holds true, so he is most qualified to comment on how it's done. Off the top of my head I don't recall if this is done by suspending threads or if the GC doesn't allow movement of these referents while the references are in use. I know I have a copy of Anthony's paper somewhere, so if you are curious, let me know and I can send you the link. Thanks, Randy Coleburn -----Original Message----- From: JC Chu [mailto:jcchu at rerouted.org] On Behalf Of JC Chu Sent: Monday, March 03, 2014 8:26 AM To: mika at async.caltech.edu; Rodney M. Bates Cc: ^M3DEVEL Subject: EXT:Re: [M3devel] REFANY-keyed tables? > Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). >>> 5. But then y still has the old value: st(y) = s. >> With a correctly implemented GC (which we have), step 5 can't happen. > If x and y point to the same object and you don't assign to them, they keep pointing to the same object. Hmm... I'll glad this is the case, but I don't see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? - JC Chu ---------------------------------------- > To: jcchu at acm.org > CC: mika at async.caltech.edu; m3devel at elegosoft.com > To: rodney_bates at lcwb.coop > Subject: Re: [M3devel] REFANY-keyed tables? > Date: Sun, 2 Mar 2014 12:17:41 -0800 > From: mika at async.caltech.edu > > > Right, right. > > Another way of seeing it is that if st(x) = st(y) then x and y are > pointing to the same object. The language specification does talk > about memory, albeit abstractly. > > If x and y point to the same object and you don't assign to them, they > keep pointing to the same object. That is the language semantics, and > yes, by The Green Book I mean Systems Programming with Modula-3. > > And yeah whatever the implementation does has to respect the language > semantics. If the GC wants to change the bit representation of x then > it has to change the bit representation of y in a way such that your > program will always see x = y. Note that it is NOT literally required > that the bit representation of x always equals the bit representation > of y. But I do believe the GC accomplishes x = y by ensuring that > their bit representations are always equal in any state where they may > be checked by your program. > > Another way of looking at this is to consider references in the > language as products of NEW. Every reference to a particular > evaluation of NEW always points to the same thing. If NEW has only > been evaluated once in your program, there can only be two REFANYs: > NIL and the result of that NEW. Those are the language semantics. And > of course the implementation has to go to some effort to ensure this > property holds even as it fiddles with the bit representations of the > two REFANYs. (NIL's bit representation is *probably* constant, but it > doesn't have to be...) > > Mika > > "Rodney M. Bates" writes: >> >> >>On 03/02/2014 09:00 AM, JC Chu wrote: >>>> You can't apply ^ to REFANY. >>> >>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>> >>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>> 3. Then the GC creates a copy s' of s. >>> 4. Then the GC updates x so that st(x) = s'. >>> 5. But then y still has the old value: st(y) = s. >> >>With a correctly implemented GC (which we have), step 5 can't happen. >>The GC will prevent any use of y by a running mutator thread until it >>(the GC) has updated y as well as x, so x = y again. My questions to >>Tony were about how the >>M3 GC accomplishes this, and it does. >> >>The motivatation for not giving REFANY a succeeding Hash is that, >>after the updates, x = y # . >>This would make a hash table fail, even if x = y works as defined. >>Mika is right, as long as you stay in the safe subset of the language. >>You simply can't write a hash function on a REFANY at all. >> >>Somebody could, however, declare the module with the Hash function >>UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if >>the sizes were not the same), and return that or something derived from it. >> >>It is never feasible in any language to define everything that can >>happen, when type-unsafe techniques are used. That inevitably gets >>into implementation details, which we often make assumptions about >>rather cavalierly. Part of the wisdom of Modula-3 is that it clearly >>defines what the safe subset is, then equally clearly defines the >>semantics of that,, without getting into implementation. >> >>I was careless about glossing over the safe/unsafe distinction. >> >>> >>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x >>> is stored in a container for REFANY, then a membership check for x >>> using y will fail, >> because it can only be based on Refany.Equal. (If T.Equal is used >> then we won't have this problem.) >>> >>>> REFANY behaves the way the Green Book says it does. >>> >>> You mean Systems Programming with Modula-3? >>> >>> - JC Chu >>> >>> -----Original Message----- >>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>> Sent: Sunday, March 2, 2014 21:03 >>> To: JC Chu; rodney_bates at lcwb.coop >>> Cc: m3devel at elegosoft.com >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> >>> >>> I just want to make an observation... >>> >>> REFANY behaves the way the Green Book says it does. There's not a >>> word in there about concurrent garbage collectors or bit-pattern >>> representations of RE >>FANY. >>> >>> If a, b : REFANY and a = b then a and b point to the same object. >>> >>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>> (Not because the garbage collector is implemented one way or >>> another.) >>> >>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>> >>> The rest is implementation... >>> >>> I'm not saying there isn't a lot of implementation, or that the >>> implementation doesn't have to get clever about some things, but you >>> really don't need to >> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>> >>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>> It defeats the purpose of REFANY. >>> >>> If you MUST hash a whole bunch of objects that have being REFANY as >>> their only thing in common I'd suggest using TYPECODE and >>> registering hash procedures >> for each type you're interested in. This is a simple enough thing >>that Modula-3's runtime "introspection" facilities more than suffice. >>(Those facilitie s are more limited than Java's, for mostly good >>reasons.) >>> >>> Mika >>> From jcchu at acm.org Tue Mar 4 01:04:16 2014 From: jcchu at acm.org (JC Chu) Date: Tue, 4 Mar 2014 08:04:16 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <0BB8FA59C2932741A3A2941A8B9D8BFF925EE54F@ATLEX04-SRV.SCIRES.LOCAL> References: <0BB8FA59C2932741A3A2941A8B9D8BFF925EE54F@ATLEX04-SRV.SCIRES.LOCAL> Message-ID: > For the CM3 implementation, Anthony Hosking has worked the GC "magic" to make sure the X=Y property holds true, so he is most qualified to comment on how it's done. Off the top of my head I don't recall if this is done by suspending threads or if the GC doesn't allow movement of these referents while the references are in use. I know I have a copy of Anthony's paper somewhere, so if you are curious, let me know and I can send you the link. Thanks, but I guess I?ll need to learn some basics about garbage collection before reading it. For the moment I?m happy that the GC just works as expected. ? JC Chu -----Original Message----- From: Coleburn, Randy [mailto:rcolebur at SCIRES.COM] Sent: Tuesday, March 4, 2014 6:57 To: JC Chu; mika at async.caltech.edu; Rodney M. Bates Cc: m3devel at elegosoft.com Subject: RE: [M3devel] REFANY-keyed tables? JC: My understanding is that this is NOT an implementation-specific property, but rather it is a language property/requirement that all implementations must meet. *If* the implementation's GC were to move things around, it would have to update *all* references to point to the new location BEFORE allowing any thread to use the reference, thereby preventing incorrect use of the old location. So, if X and Y are references AND if X=Y (i.e. they reference the same thing), the implementation must ensure X=Y remains valid for all threads of execution even if the GC chooses to relocate the referents. For the CM3 implementation, Anthony Hosking has worked the GC "magic" to make sure the X=Y property holds true, so he is most qualified to comment on how it's done. Off the top of my head I don't recall if this is done by suspending threads or if the GC doesn't allow movement of these referents while the references are in use. I know I have a copy of Anthony's paper somewhere, so if you are curious, let me know and I can send you the link. Thanks, Randy Coleburn -----Original Message----- From: JC Chu [mailto:jcchu at rerouted.org] On Behalf Of JC Chu Sent: Monday, March 03, 2014 8:26 AM To: mika at async.caltech.edu; Rodney M. Bates Cc: ^M3DEVEL Subject: EXT:Re: [M3devel] REFANY-keyed tables? > Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). >>> 5. But then y still has the old value: st(y) = s. >> With a correctly implemented GC (which we have), step 5 can't happen. > If x and y point to the same object and you don't assign to them, they keep pointing to the same object. Hmm... I'll glad this is the case, but I don't see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? - JC Chu ---------------------------------------- > To: jcchu at acm.org > CC: mika at async.caltech.edu; m3devel at elegosoft.com > To: rodney_bates at lcwb.coop > Subject: Re: [M3devel] REFANY-keyed tables? > Date: Sun, 2 Mar 2014 12:17:41 -0800 > From: mika at async.caltech.edu > > > Right, right. > > Another way of seeing it is that if st(x) = st(y) then x and y are > pointing to the same object. The language specification does talk > about memory, albeit abstractly. > > If x and y point to the same object and you don't assign to them, they > keep pointing to the same object. That is the language semantics, and > yes, by The Green Book I mean Systems Programming with Modula-3. > > And yeah whatever the implementation does has to respect the language > semantics. If the GC wants to change the bit representation of x then > it has to change the bit representation of y in a way such that your > program will always see x = y. Note that it is NOT literally required > that the bit representation of x always equals the bit representation > of y. But I do believe the GC accomplishes x = y by ensuring that > their bit representations are always equal in any state where they may > be checked by your program. > > Another way of looking at this is to consider references in the > language as products of NEW. Every reference to a particular > evaluation of NEW always points to the same thing. If NEW has only > been evaluated once in your program, there can only be two REFANYs: > NIL and the result of that NEW. Those are the language semantics. And > of course the implementation has to go to some effort to ensure this > property holds even as it fiddles with the bit representations of the > two REFANYs. (NIL's bit representation is *probably* constant, but it > doesn't have to be...) > > Mika > > "Rodney M. Bates" writes: >> >> >>On 03/02/2014 09:00 AM, JC Chu wrote: >>>> You can't apply ^ to REFANY. >>> >>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>> >>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>> 3. Then the GC creates a copy s' of s. >>> 4. Then the GC updates x so that st(x) = s'. >>> 5. But then y still has the old value: st(y) = s. >> >>With a correctly implemented GC (which we have), step 5 can't happen. >>The GC will prevent any use of y by a running mutator thread until it >>(the GC) has updated y as well as x, so x = y again. My questions to >>Tony were about how the >>M3 GC accomplishes this, and it does. >> >>The motivatation for not giving REFANY a succeeding Hash is that, >>after the updates, x = y # . >>This would make a hash table fail, even if x = y works as defined. >>Mika is right, as long as you stay in the safe subset of the language. >>You simply can't write a hash function on a REFANY at all. >> >>Somebody could, however, declare the module with the Hash function >>UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if >>the sizes were not the same), and return that or something derived from it. >> >>It is never feasible in any language to define everything that can >>happen, when type-unsafe techniques are used. That inevitably gets >>into implementation details, which we often make assumptions about >>rather cavalierly. Part of the wisdom of Modula-3 is that it clearly >>defines what the safe subset is, then equally clearly defines the >>semantics of that,, without getting into implementation. >> >>I was careless about glossing over the safe/unsafe distinction. >> >>> >>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x >>> is stored in a container for REFANY, then a membership check for x >>> using y will fail, >> because it can only be based on Refany.Equal. (If T.Equal is used >> then we won't have this problem.) >>> >>>> REFANY behaves the way the Green Book says it does. >>> >>> You mean Systems Programming with Modula-3? >>> >>> - JC Chu >>> >>> -----Original Message----- >>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>> Sent: Sunday, March 2, 2014 21:03 >>> To: JC Chu; rodney_bates at lcwb.coop >>> Cc: m3devel at elegosoft.com >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> >>> >>> I just want to make an observation... >>> >>> REFANY behaves the way the Green Book says it does. There's not a >>> word in there about concurrent garbage collectors or bit-pattern >>> representations of RE >>FANY. >>> >>> If a, b : REFANY and a = b then a and b point to the same object. >>> >>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>> (Not because the garbage collector is implemented one way or >>> another.) >>> >>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>> >>> The rest is implementation... >>> >>> I'm not saying there isn't a lot of implementation, or that the >>> implementation doesn't have to get clever about some things, but you >>> really don't need to >> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>> >>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>> It defeats the purpose of REFANY. >>> >>> If you MUST hash a whole bunch of objects that have being REFANY as >>> their only thing in common I'd suggest using TYPECODE and >>> registering hash procedures >> for each type you're interested in. This is a simple enough thing >>that Modula-3's runtime "introspection" facilities more than suffice. >>(Those facilitie s are more limited than Java's, for mostly good >>reasons.) >>> >>> Mika >>> From mika at async.caltech.edu Tue Mar 4 01:33:02 2014 From: mika at async.caltech.edu (mika at async.caltech.edu) Date: Mon, 03 Mar 2014 16:33:02 -0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop> <20140302201741.C42E71A2094@async.async.caltech.edu> <3E55E8A6-AF96-451D-9E94-3645DD4F050C@purdue.edu> Message-ID: <20140304003302.7B67E1A2094@async.async.caltech.edu> Here is the simple way of thinking about garbage collectors: The only thing that your program might do differently if you turn off the garbage collector is run out of memory sooner. Nothing else about its behavior should change---any change would point to a mistake in the implementation of the garbage collector. Mika JC Chu writes: >I see. So it is expected for garbage collectors to ensure that, as Tony = >put it, =E2=80=98every reference to a particular evaluation of NEW = >always points to the same thing=E2=80=99. > >=E2=80=94 JC Chu > >-----Original Message----- >From: Antony Hosking [mailto:hosking at purdue.edu]=20 >Sent: Monday, March 3, 2014 22:58 >To: JC Chu >Cc: mika at async.caltech.edu; Rodney M. Bates; ^M3DEVEL >Subject: Re: [M3devel] REFANY-keyed tables? > >The GC maintains what is called a to-space invariant: all mutators are = >switched to the copy space before the collector starts moving objects. = >The read barrier ensures that mutators can never see old space objects. = >But as Mika notes, this is an implementation detail that ensures the = >language semantics in which reference equality just works as you would = >expect. The same is true of Java or any garbage collected language. > >Sent from my iPad > >On Mar 3, 2014, at 8:25 AM, JC Chu wrote: > >>> Another way of seeing it is that if st(x) =3D st(y) then x and y are = >pointing to the same object. >>=20 >>=20 >> Well the language definition does state that st(x) =3D st(y) implies x = >=3D y (and the opposite implication is obvious). >>=20 >>=20 >>>>> 5. But then y still has the old value: st(y) =3D s. >>=20 >>=20 >>>> With a correctly implemented GC (which we have), step 5 can't = >happen. >>=20 >>=20 >>> If x and y point to the same object and you don't assign to them, = >they keep pointing to the same object. >>=20 >>=20 >> Hmm... I=E2=80=99ll glad this is the case, but I don=E2=80=99t see = >how it follows from the language definition alone. I mean the GC itself = >changes things on its own, without my having to assign to anything. If = >some poor GC did let step 5 happen and we have x # y and st(x) # st(y), = >it is still consistent with x =3D y iff st(x) =3D st(y). So this nice = >property is implementation-specific after all... Or did I miss anything = >from the language definition? >>=20 >> =E2=80=94 JC Chu >>=20 >>=20 >> ---------------------------------------- >>> To: jcchu at acm.org >>> CC: mika at async.caltech.edu; m3devel at elegosoft.com >>> To: rodney_bates at lcwb.coop >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> Date: Sun, 2 Mar 2014 12:17:41 -0800 >>> From: mika at async.caltech.edu >>>=20 >>>=20 >>> Right, right. >>>=20 >>> Another way of seeing it is that if st(x) =3D st(y) then x and y are=20 >>> pointing to the same object. The language specification does talk=20 >>> about memory, albeit abstractly. >>>=20 >>> If x and y point to the same object and you don't assign to them,=20 >>> they keep pointing to the same object. That is the language=20 >>> semantics, and yes, by The Green Book I mean Systems Programming with = >Modula-3. >>>=20 >>> And yeah whatever the implementation does has to respect the language = > >>> semantics. If the GC wants to change the bit representation of x then = > >>> it has to change the bit representation of y in a way such that your=20 >>> program will always see x =3D y. Note that it is NOT literally = >required=20 >>> that the bit representation of x always equals the bit representation = > >>> of y. But I do believe the GC accomplishes x =3D y by ensuring that=20 >>> their bit representations are always equal in any state where they=20 >>> may be checked by your program. >>>=20 >>> Another way of looking at this is to consider references in the=20 >>> language as products of NEW. Every reference to a particular=20 >>> evaluation of NEW always points to the same thing. If NEW has only=20 >>> been evaluated once in your program, there can only be two REFANYs:=20 >>> NIL and the result of that NEW. Those are the language semantics. And = > >>> of course the implementation has to go to some effort to ensure this=20 >>> property holds even as it fiddles with the bit representations of the = > >>> two REFANYs. (NIL's bit representation is *probably* constant, but it = > >>> doesn't have to be...) >>>=20 >>> Mika >>>=20 >>> "Rodney M. Bates" writes: >>>>=20 >>>>=20 >>>> On 03/02/2014 09:00 AM, JC Chu wrote: >>>>>> You can't apply ^ to REFANY. >>>>>=20 >>>>> That was a mistake on my part. Let me rephrase my worry as follows, = >where st(r) denotes the storage location pointed to by the reference r. >>>>>=20 >>>>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>>>> 2. Initially, x =3D y # NIL and st(x) =3D st(y) =3D s. >>>>> 3. Then the GC creates a copy s' of s. >>>>> 4. Then the GC updates x so that st(x) =3D s'. >>>>> 5. But then y still has the old value: st(y) =3D s. >>>>=20 >>>> With a correctly implemented GC (which we have), step 5 can't=20 >>>> happen. The GC will prevent any use of y by a running mutator thread = > >>>> until it (the GC) has updated y as well as x, so x =3D y again. My=20 >>>> questions to Tony were about how the >>>> M3 GC accomplishes this, and it does. >>>>=20 >>>> The motivatation for not giving REFANY a succeeding Hash is that,=20 >>>> after the updates, x =3D y # move>.=20 >>>> This would make a hash table fail, even if x =3D y works as defined. = > >>>> Mika is right, as long as you stay in the safe subset of the=20 >>>> language. You simply can't write a hash function on a REFANY at all. >>>>=20 >>>> Somebody could, however, declare the module with the Hash function=20 >>>> UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if = > >>>> the sizes were not the same), and return that or something derived = >from it. >>>>=20 >>>> It is never feasible in any language to define everything that can=20 >>>> happen, when type-unsafe techniques are used. That inevitably gets=20 >>>> into implementation details, which we often make assumptions about=20 >>>> rather cavalierly. Part of the wisdom of Modula-3 is that it clearly = > >>>> defines what the safe subset is, then equally clearly defines the=20 >>>> semantics of that,, without getting into implementation. >>>>=20 >>>> I was careless about glossing over the safe/unsafe distinction. >>>>=20 >>>>>=20 >>>>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x=20 >>>>> is stored in a container for REFANY, then a membership check for x=20 >>>>> using y will fail, >>>> because it can only be based on Refany.Equal. (If T.Equal is used=20 >>>> then we won=E2=80=99t have this problem.) >>>>>=20 >>>>>> REFANY behaves the way the Green Book says it does. >>>>>=20 >>>>> You mean Systems Programming with Modula-3? >>>>>=20 >>>>> =E2=80=94 JC Chu >>>>>=20 >>>>> -----Original Message----- >>>>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>>>> Sent: Sunday, March 2, 2014 21:03 >>>>> To: JC Chu; rodney_bates at lcwb.coop >>>>> Cc: m3devel at elegosoft.com >>>>> Subject: Re: [M3devel] REFANY-keyed tables? >>>>>=20 >>>>>=20 >>>>> I just want to make an observation... >>>>>=20 >>>>> REFANY behaves the way the Green Book says it does. There's not a=20 >>>>> word in there about concurrent garbage collectors or bit-pattern=20 >>>>> representations of RE >>>> FANY. >>>>>=20 >>>>> If a, b : REFANY and a =3D b then a and b point to the same object. >>>>>=20 >>>>> You can't apply ^ to REFANY. The only thing you can do to a value = >beyond =3D is narrow it to another type. That's why there's no Hash for = >REFANY. >>>>> (Not because the garbage collector is implemented one way or=20 >>>>> another.) >>>>>=20 >>>>> Of course you can put REFANY in a list. You can make as many copies = >in as many places as you want and =3D will continue working. >>>>>=20 >>>>> The rest is implementation... >>>>>=20 >>>>> I'm not saying there isn't a lot of implementation, or that the=20 >>>>> implementation doesn't have to get clever about some things, but=20 >>>>> you really don't need to >>>> think about the implementation to know what you can and can't do = >with REFANY. It's all in the Green Book. >>>>>=20 >>>>> I definitely would not suggest messing with the garbage collector = >because you want to get something working with REFANY in a pure Modula-3 = >program. >>>>> It defeats the purpose of REFANY. >>>>>=20 >>>>> If you MUST hash a whole bunch of objects that have being REFANY as = > >>>>> their only thing in common I'd suggest using TYPECODE and=20 >>>>> registering hash procedures >>>> for each type you're interested in. This is a simple enough thing=20 >>>> that Modula-3's runtime "introspection" facilities more than=20 >>>> suffice. (Those facilitie s are more limited than Java's, for mostly = > >>>> good reasons.) >>>>>=20 >>>>> Mika >>>>> =20 From jcchu at acm.org Tue Mar 4 01:03:33 2014 From: jcchu at acm.org (JC Chu) Date: Tue, 4 Mar 2014 08:03:33 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <3E55E8A6-AF96-451D-9E94-3645DD4F050C@purdue.edu> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop> <20140302201741.C42E71A2094@async.async.caltech.edu> <3E55E8A6-AF96-451D-9E94-3645DD4F050C@purdue.edu> Message-ID: I see. So it is expected for garbage collectors to ensure that, as Tony put it, ?every reference to a particular evaluation of NEW always points to the same thing?. ? JC Chu -----Original Message----- From: Antony Hosking [mailto:hosking at purdue.edu] Sent: Monday, March 3, 2014 22:58 To: JC Chu Cc: mika at async.caltech.edu; Rodney M. Bates; ^M3DEVEL Subject: Re: [M3devel] REFANY-keyed tables? The GC maintains what is called a to-space invariant: all mutators are switched to the copy space before the collector starts moving objects. The read barrier ensures that mutators can never see old space objects. But as Mika notes, this is an implementation detail that ensures the language semantics in which reference equality just works as you would expect. The same is true of Java or any garbage collected language. Sent from my iPad On Mar 3, 2014, at 8:25 AM, JC Chu wrote: >> Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. > > > Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). > > >>>> 5. But then y still has the old value: st(y) = s. > > >>> With a correctly implemented GC (which we have), step 5 can't happen. > > >> If x and y point to the same object and you don't assign to them, they keep pointing to the same object. > > > Hmm... I?ll glad this is the case, but I don?t see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? > > ? JC Chu > > > ---------------------------------------- >> To: jcchu at acm.org >> CC: mika at async.caltech.edu; m3devel at elegosoft.com >> To: rodney_bates at lcwb.coop >> Subject: Re: [M3devel] REFANY-keyed tables? >> Date: Sun, 2 Mar 2014 12:17:41 -0800 >> From: mika at async.caltech.edu >> >> >> Right, right. >> >> Another way of seeing it is that if st(x) = st(y) then x and y are >> pointing to the same object. The language specification does talk >> about memory, albeit abstractly. >> >> If x and y point to the same object and you don't assign to them, >> they keep pointing to the same object. That is the language >> semantics, and yes, by The Green Book I mean Systems Programming with Modula-3. >> >> And yeah whatever the implementation does has to respect the language >> semantics. If the GC wants to change the bit representation of x then >> it has to change the bit representation of y in a way such that your >> program will always see x = y. Note that it is NOT literally required >> that the bit representation of x always equals the bit representation >> of y. But I do believe the GC accomplishes x = y by ensuring that >> their bit representations are always equal in any state where they >> may be checked by your program. >> >> Another way of looking at this is to consider references in the >> language as products of NEW. Every reference to a particular >> evaluation of NEW always points to the same thing. If NEW has only >> been evaluated once in your program, there can only be two REFANYs: >> NIL and the result of that NEW. Those are the language semantics. And >> of course the implementation has to go to some effort to ensure this >> property holds even as it fiddles with the bit representations of the >> two REFANYs. (NIL's bit representation is *probably* constant, but it >> doesn't have to be...) >> >> Mika >> >> "Rodney M. Bates" writes: >>> >>> >>> On 03/02/2014 09:00 AM, JC Chu wrote: >>>>> You can't apply ^ to REFANY. >>>> >>>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>>> >>>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>>> 3. Then the GC creates a copy s' of s. >>>> 4. Then the GC updates x so that st(x) = s'. >>>> 5. But then y still has the old value: st(y) = s. >>> >>> With a correctly implemented GC (which we have), step 5 can't >>> happen. The GC will prevent any use of y by a running mutator thread >>> until it (the GC) has updated y as well as x, so x = y again. My >>> questions to Tony were about how the >>> M3 GC accomplishes this, and it does. >>> >>> The motivatation for not giving REFANY a succeeding Hash is that, >>> after the updates, x = y # . >>> This would make a hash table fail, even if x = y works as defined. >>> Mika is right, as long as you stay in the safe subset of the >>> language. You simply can't write a hash function on a REFANY at all. >>> >>> Somebody could, however, declare the module with the Hash function >>> UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if >>> the sizes were not the same), and return that or something derived from it. >>> >>> It is never feasible in any language to define everything that can >>> happen, when type-unsafe techniques are used. That inevitably gets >>> into implementation details, which we often make assumptions about >>> rather cavalierly. Part of the wisdom of Modula-3 is that it clearly >>> defines what the safe subset is, then equally clearly defines the >>> semantics of that,, without getting into implementation. >>> >>> I was careless about glossing over the safe/unsafe distinction. >>> >>>> >>>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x >>>> is stored in a container for REFANY, then a membership check for x >>>> using y will fail, >>> because it can only be based on Refany.Equal. (If T.Equal is used >>> then we won?t have this problem.) >>>> >>>>> REFANY behaves the way the Green Book says it does. >>>> >>>> You mean Systems Programming with Modula-3? >>>> >>>> ? JC Chu >>>> >>>> -----Original Message----- >>>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>>> Sent: Sunday, March 2, 2014 21:03 >>>> To: JC Chu; rodney_bates at lcwb.coop >>>> Cc: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] REFANY-keyed tables? >>>> >>>> >>>> I just want to make an observation... >>>> >>>> REFANY behaves the way the Green Book says it does. There's not a >>>> word in there about concurrent garbage collectors or bit-pattern >>>> representations of RE >>> FANY. >>>> >>>> If a, b : REFANY and a = b then a and b point to the same object. >>>> >>>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>>> (Not because the garbage collector is implemented one way or >>>> another.) >>>> >>>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>>> >>>> The rest is implementation... >>>> >>>> I'm not saying there isn't a lot of implementation, or that the >>>> implementation doesn't have to get clever about some things, but >>>> you really don't need to >>> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>>> >>>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>>> It defeats the purpose of REFANY. >>>> >>>> If you MUST hash a whole bunch of objects that have being REFANY as >>>> their only thing in common I'd suggest using TYPECODE and >>>> registering hash procedures >>> for each type you're interested in. This is a simple enough thing >>> that Modula-3's runtime "introspection" facilities more than >>> suffice. (Those facilitie s are more limited than Java's, for mostly >>> good reasons.) >>>> >>>> Mika >>>> From hendrik at topoi.pooq.com Thu Mar 20 20:39:38 2014 From: hendrik at topoi.pooq.com (Hendrik Boom) Date: Thu, 20 Mar 2014 15:39:38 -0400 Subject: [M3devel] musl Message-ID: <20140320193938.GA18041@topoi.pooq.com> There's a new C library on the block. I don't know if this is at all relevant for Modula 3 implementation, but I thought i should mention it in case it is: http://www.musl-libc.org/ If nothing else, it has a different license. -- hendrik From jay.krell at cornell.edu Thu Mar 20 22:29:15 2014 From: jay.krell at cornell.edu (Jay K) Date: Thu, 20 Mar 2014 21:29:15 +0000 Subject: [M3devel] musl In-Reply-To: <20140320193938.GA18041@topoi.pooq.com> References: <20140320193938.GA18041@topoi.pooq.com> Message-ID: All of our use of the C library is from C/C++ now, not from Modula-3 directly. There is no longer C-library specific code/rewritten headers. Whatever your C compiler/flags use is what Modula-3 uses. - Jay > Date: Thu, 20 Mar 2014 15:39:38 -0400 > From: hendrik at topoi.pooq.com > To: m3devel at elegosoft.com > Subject: [M3devel] musl > > There's a new C library on the block. I don't know if this is at all > relevant for Modula 3 implementation, but I thought i should mention it > in case it is: > > http://www.musl-libc.org/ > > If nothing else, it has a different license. > > -- hendrik > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sat Mar 1 19:12:36 2014 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sat, 1 Mar 2014 19:12:36 +0100 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> Message-ID: I am not following this thread so well, but? Why do you need something like this? Maybe to use it as an argument to a C callback? On 28 Feb 2014, at 18:40, JC Chu wrote: >> ... The above technique works if you really want to simulate keying on the address (as it would be in a no-move GC environment.), which I suppose is what you wanted. > > Yes, I was indeed in need of an immutable version of REFANY. > > ? JC Chu > > -----Original Message----- > From: Rodney M. Bates [mailto:rodney_bates at lcwb.coop] > Sent: Friday, February 28, 2014 23:16 > To: m3devel at elegosoft.com > Subject: Re: [M3devel] REFANY-keyed tables? > > > > On 02/26/2014 09:28 PM, Rodney M. Bates wrote: >> >> >> On 02/26/2014 11:08 AM, JC Chu wrote: >>> Hi, >>> >>> I need a REFANY-to-INTEGER table in my program but RefIntTbl.Default is giving me runtime errors. Apparently Table(Key, Value) uses Key.Equal() and Key.Hash(), but those procedures in Refany, which is use to instantiate RefIntTbl, both raise a fatal exception. >>> >> >> The garbage collector is a (partially) compacting collector, which >> means it can move a heap object and adjust all the pointers to it, if >> it knows where they all are, which holds for some objects. So the bit >> contents of a REFANY can change. This means it is not possible to have a consistent Hash on the pointer value alone. >> >> So Refany.Hash is deliberately coded to raise this exception, to >> prevent a far more insidious bug. >> >>> I?m a bit confused since a number of REFANY-keyed tables are shipped with CM3. Is this actually the expected behavior or am I doing anything wrong? >>> >> >> Hmm, can you point out where these are? >> >> I have some pointer-keyed tables, but they use techniques like giving >> every object an object sequence number field, explicitly initialized >> when an object is allocated, and using that for the Hash function. >> But this won't work for REFANY, because it can have no fields. >> > > There is more to this. The above technique works if you really want to simulate keying on the address (as it would be in a no-move GC environment.), which I suppose is what you wanted. > > But in many cases, you might want to hash on the contents, not the address of the object, in which case, the technique used in juno-2, using actual data fields instead of an object sequence number is the right way. For example, to turn the objects into atoms. > >> So the table can only work on a narrower set of allocated object types than REFANY. >> If you need the table to hold addresses of a mixture of different >> types, you can still do that with a hierarchy of OBJECT types, but >> they will have to have a common supertype that contains whatever fields the Hash function needs for consistency. >> >> It would be possible that pointers get passed around in REFANY-typed >> (statically) variables, but it is carefully arranged that they all >> have an allocated type that has fields a Hash function can work on. >> Hash would then have to do a NARROW or TYPECASE to the type it expected. >> >> Rodney Bates >> >>> Thanks. >>> >>> ? JC Chu >>> >> >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From jcchu at acm.org Sun Mar 2 06:09:48 2014 From: jcchu at acm.org (JC Chu) Date: Sun, 2 Mar 2014 13:09:48 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , Message-ID: Oh I just needed to count the number of times each object has been visited, where objects a and b are considered identical iff Refany.Equal(a, b), so tagging objects with sequential integers and using instead an INTEGER-to-INTEGER table sufficed. - JC Chu ---------------------------------------- > Subject: Re: [M3devel] REFANY-keyed tables? > From: dragisha at m3w.org > Date: Sat, 1 Mar 2014 19:12:36 +0100 > CC: rodney_bates at lcwb.coop; m3devel at elegosoft.com > To: jcchu at acm.org > > I am not following this thread so well, but. Why do you need something like this? Maybe to use it as an argument to a C callback? > From mika at async.caltech.edu Sun Mar 2 14:02:43 2014 From: mika at async.caltech.edu (mika at async.caltech.edu) Date: Sun, 02 Mar 2014 05:02:43 -0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , Message-ID: <20140302130243.7BD831A2095@async.async.caltech.edu> I just want to make an observation... REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of REFANY. If a, b : REFANY and a = b then a and b point to the same object. You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. (Not because the garbage collector is implemented one way or another.) Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. The rest is implementation... I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. It defeats the purpose of REFANY. If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilities are more limited than Java's, for mostly good reasons.) Mika From jcchu at acm.org Sun Mar 2 16:00:25 2014 From: jcchu at acm.org (JC Chu) Date: Sun, 2 Mar 2014 23:00:25 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <20140302130243.7BD831A2095@async.async.caltech.edu> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> Message-ID: > You can't apply ^ to REFANY. That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. 1. x, y: REF T, where T has an equivalence relation T.Equal. 2. Initially, x = y # NIL and st(x) = st(y) = s. 3. Then the GC creates a copy s' of s. 4. Then the GC updates x so that st(x) = s'. 5. But then y still has the old value: st(y) = s. At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, because it can only be based on Refany.Equal. (If T.Equal is used then we won?t have this problem.) > REFANY behaves the way the Green Book says it does. You mean Systems Programming with Modula-3? ? JC Chu -----Original Message----- From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] Sent: Sunday, March 2, 2014 21:03 To: JC Chu; rodney_bates at lcwb.coop Cc: m3devel at elegosoft.com Subject: Re: [M3devel] REFANY-keyed tables? I just want to make an observation... REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of REFANY. If a, b : REFANY and a = b then a and b point to the same object. You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. (Not because the garbage collector is implemented one way or another.) Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. The rest is implementation... I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. It defeats the purpose of REFANY. If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilities are more limited than Java's, for mostly good reasons.) Mika From rodney_bates at lcwb.coop Sun Mar 2 20:57:08 2014 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sun, 02 Mar 2014 13:57:08 -0600 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> Message-ID: <53138D14.2030102@lcwb.coop> On 03/02/2014 09:00 AM, JC Chu wrote: >> You can't apply ^ to REFANY. > > That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. > > 1. x, y: REF T, where T has an equivalence relation T.Equal. > 2. Initially, x = y # NIL and st(x) = st(y) = s. > 3. Then the GC creates a copy s' of s. > 4. Then the GC updates x so that st(x) = s'. > 5. But then y still has the old value: st(y) = s. With a correctly implemented GC (which we have), step 5 can't happen. The GC will prevent any use of y by a running mutator thread until it (the GC) has updated y as well as x, so x = y again. My questions to Tony were about how the M3 GC accomplishes this, and it does. The motivatation for not giving REFANY a succeeding Hash is that, after the updates, x = y # . This would make a hash table fail, even if x = y works as defined. Mika is right, as long as you stay in the safe subset of the language. You simply can't write a hash function on a REFANY at all. Somebody could, however, declare the module with the Hash function UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if the sizes were not the same), and return that or something derived from it. It is never feasible in any language to define everything that can happen, when type-unsafe techniques are used. That inevitably gets into implementation details, which we often make assumptions about rather cavalierly. Part of the wisdom of Modula-3 is that it clearly defines what the safe subset is, then equally clearly defines the semantics of that,, without getting into implementation. I was careless about glossing over the safe/unsafe distinction. > > At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, because it can only be based on Refany.Equal. (If T.Equal is used then we won?t have this problem.) > >> REFANY behaves the way the Green Book says it does. > > You mean Systems Programming with Modula-3? > > ? JC Chu > > -----Original Message----- > From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] > Sent: Sunday, March 2, 2014 21:03 > To: JC Chu; rodney_bates at lcwb.coop > Cc: m3devel at elegosoft.com > Subject: Re: [M3devel] REFANY-keyed tables? > > > I just want to make an observation... > > REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of REFANY. > > If a, b : REFANY and a = b then a and b point to the same object. > > You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. > (Not because the garbage collector is implemented one way or another.) > > Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. > > The rest is implementation... > > I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. > > I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. > It defeats the purpose of REFANY. > > If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilities are more limited than Java's, for mostly good reasons.) > > Mika > From mika at async.caltech.edu Sun Mar 2 21:17:41 2014 From: mika at async.caltech.edu (mika at async.caltech.edu) Date: Sun, 02 Mar 2014 12:17:41 -0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <53138D14.2030102@lcwb.coop> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop> Message-ID: <20140302201741.C42E71A2094@async.async.caltech.edu> Right, right. Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. The language specification does talk about memory, albeit abstractly. If x and y point to the same object and you don't assign to them, they keep pointing to the same object. That is the language semantics, and yes, by The Green Book I mean Systems Programming with Modula-3. And yeah whatever the implementation does has to respect the language semantics. If the GC wants to change the bit representation of x then it has to change the bit representation of y in a way such that your program will always see x = y. Note that it is NOT literally required that the bit representation of x always equals the bit representation of y. But I do believe the GC accomplishes x = y by ensuring that their bit representations are always equal in any state where they may be checked by your program. Another way of looking at this is to consider references in the language as products of NEW. Every reference to a particular evaluation of NEW always points to the same thing. If NEW has only been evaluated once in your program, there can only be two REFANYs: NIL and the result of that NEW. Those are the language semantics. And of course the implementation has to go to some effort to ensure this property holds even as it fiddles with the bit representations of the two REFANYs. (NIL's bit representation is *probably* constant, but it doesn't have to be...) Mika "Rodney M. Bates" writes: > > >On 03/02/2014 09:00 AM, JC Chu wrote: >>> You can't apply ^ to REFANY. >> >> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >> >> 1. x, y: REF T, where T has an equivalence relation T.Equal. >> 2. Initially, x = y # NIL and st(x) = st(y) = s. >> 3. Then the GC creates a copy s' of s. >> 4. Then the GC updates x so that st(x) = s'. >> 5. But then y still has the old value: st(y) = s. > >With a correctly implemented GC (which we have), step 5 can't happen. The GC >will prevent any use of y by a running mutator thread until it (the GC) has >updated y as well as x, so x = y again. My questions to Tony were about how the >M3 GC accomplishes this, and it does. > >The motivatation for not giving REFANY a succeeding Hash is that, after >the updates, x = y # . This would >make a hash table fail, even if x = y works as defined. Mika is right, >as long as you stay in the safe subset of the language. You simply can't >write a hash function on a REFANY at all. > >Somebody could, however, declare the module with the Hash function UNSAFE, >LOOPHOLE the REFANY value to a Word.T (or something else, if the sizes were >not the same), and return that or something derived from it. > >It is never feasible in any language to define everything that can happen, >when type-unsafe techniques are used. That inevitably gets into implementation >details, which we often make assumptions about rather cavalierly. Part of >the wisdom of Modula-3 is that it clearly defines what the safe subset is, >then equally clearly defines the semantics of that,, without getting into >implementation. > >I was careless about glossing over the safe/unsafe distinction. > >> >> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, > because it can only be based on Refany.Equal. (If T.Equal is used then we won???t have this problem.) >> >>> REFANY behaves the way the Green Book says it does. >> >> You mean Systems Programming with Modula-3? >> >> ??? JC Chu >> >> -----Original Message----- >> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >> Sent: Sunday, March 2, 2014 21:03 >> To: JC Chu; rodney_bates at lcwb.coop >> Cc: m3devel at elegosoft.com >> Subject: Re: [M3devel] REFANY-keyed tables? >> >> >> I just want to make an observation... >> >> REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of RE >FANY. >> >> If a, b : REFANY and a = b then a and b point to the same object. >> >> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >> (Not because the garbage collector is implemented one way or another.) >> >> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >> >> The rest is implementation... >> >> I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to > think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >> >> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >> It defeats the purpose of REFANY. >> >> If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures > for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilitie >s are more limited than Java's, for mostly good reasons.) >> >> Mika >> From jcchu at acm.org Mon Mar 3 14:25:42 2014 From: jcchu at acm.org (JC Chu) Date: Mon, 3 Mar 2014 21:25:42 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <20140302201741.C42E71A2094@async.async.caltech.edu> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop>, <20140302201741.C42E71A2094@async.async.caltech.edu> Message-ID: > Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). >>> 5. But then y still has the old value: st(y) = s. >> With a correctly implemented GC (which we have), step 5 can't happen. > If x and y point to the same object and you don't assign to them, they keep pointing to the same object. Hmm... I?ll glad this is the case, but I don?t see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? ? JC Chu ---------------------------------------- > To: jcchu at acm.org > CC: mika at async.caltech.edu; m3devel at elegosoft.com > To: rodney_bates at lcwb.coop > Subject: Re: [M3devel] REFANY-keyed tables? > Date: Sun, 2 Mar 2014 12:17:41 -0800 > From: mika at async.caltech.edu > > > Right, right. > > Another way of seeing it is that if st(x) = st(y) then x and y are > pointing to the same object. The language specification does talk about > memory, albeit abstractly. > > If x and y point to the same object and you don't assign to them, they > keep pointing to the same object. That is the language semantics, > and yes, by The Green Book I mean Systems Programming with Modula-3. > > And yeah whatever the implementation does has to respect the language > semantics. If the GC wants to change the bit representation of x then it > has to change the bit representation of y in a way such that your program > will always see x = y. Note that it is NOT literally required that the > bit representation of x always equals the bit representation of y. But > I do believe the GC accomplishes x = y by ensuring that their bit > representations are always equal in any state where they may be checked > by your program. > > Another way of looking at this is to consider references in the language > as products of NEW. Every reference to a particular evaluation of NEW > always points to the same thing. If NEW has only been evaluated once > in your program, there can only be two REFANYs: NIL and the result of > that NEW. Those are the language semantics. And of course the implementation > has to go to some effort to ensure this property holds even as it fiddles > with the bit representations of the two REFANYs. (NIL's bit representation > is *probably* constant, but it doesn't have to be...) > > Mika > > "Rodney M. Bates" writes: >> >> >>On 03/02/2014 09:00 AM, JC Chu wrote: >>>> You can't apply ^ to REFANY. >>> >>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>> >>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>> 3. Then the GC creates a copy s' of s. >>> 4. Then the GC updates x so that st(x) = s'. >>> 5. But then y still has the old value: st(y) = s. >> >>With a correctly implemented GC (which we have), step 5 can't happen. The GC >>will prevent any use of y by a running mutator thread until it (the GC) has >>updated y as well as x, so x = y again. My questions to Tony were about how the >>M3 GC accomplishes this, and it does. >> >>The motivatation for not giving REFANY a succeeding Hash is that, after >>the updates, x = y # . This would >>make a hash table fail, even if x = y works as defined. Mika is right, >>as long as you stay in the safe subset of the language. You simply can't >>write a hash function on a REFANY at all. >> >>Somebody could, however, declare the module with the Hash function UNSAFE, >>LOOPHOLE the REFANY value to a Word.T (or something else, if the sizes were >>not the same), and return that or something derived from it. >> >>It is never feasible in any language to define everything that can happen, >>when type-unsafe techniques are used. That inevitably gets into implementation >>details, which we often make assumptions about rather cavalierly. Part of >>the wisdom of Modula-3 is that it clearly defines what the safe subset is, >>then equally clearly defines the semantics of that,, without getting into >>implementation. >> >>I was careless about glossing over the safe/unsafe distinction. >> >>> >>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, >> because it can only be based on Refany.Equal. (If T.Equal is used then we won?t have this problem.) >>> >>>> REFANY behaves the way the Green Book says it does. >>> >>> You mean Systems Programming with Modula-3? >>> >>> ? JC Chu >>> >>> -----Original Message----- >>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>> Sent: Sunday, March 2, 2014 21:03 >>> To: JC Chu; rodney_bates at lcwb.coop >>> Cc: m3devel at elegosoft.com >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> >>> >>> I just want to make an observation... >>> >>> REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of RE >>FANY. >>> >>> If a, b : REFANY and a = b then a and b point to the same object. >>> >>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>> (Not because the garbage collector is implemented one way or another.) >>> >>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>> >>> The rest is implementation... >>> >>> I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to >> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>> >>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>> It defeats the purpose of REFANY. >>> >>> If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures >> for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilitie >>s are more limited than Java's, for mostly good reasons.) >>> >>> Mika >>> From rcolebur at SCIRES.COM Mon Mar 3 23:56:32 2014 From: rcolebur at SCIRES.COM (Coleburn, Randy) Date: Mon, 3 Mar 2014 22:56:32 +0000 Subject: [M3devel] REFANY-keyed tables? Message-ID: <0BB8FA59C2932741A3A2941A8B9D8BFF925EE54F@ATLEX04-SRV.SCIRES.LOCAL> JC: My understanding is that this is NOT an implementation-specific property, but rather it is a language property/requirement that all implementations must meet. *If* the implementation's GC were to move things around, it would have to update *all* references to point to the new location BEFORE allowing any thread to use the reference, thereby preventing incorrect use of the old location. So, if X and Y are references AND if X=Y (i.e. they reference the same thing), the implementation must ensure X=Y remains valid for all threads of execution even if the GC chooses to relocate the referents. For the CM3 implementation, Anthony Hosking has worked the GC "magic" to make sure the X=Y property holds true, so he is most qualified to comment on how it's done. Off the top of my head I don't recall if this is done by suspending threads or if the GC doesn't allow movement of these referents while the references are in use. I know I have a copy of Anthony's paper somewhere, so if you are curious, let me know and I can send you the link. Thanks, Randy Coleburn -----Original Message----- From: JC Chu [mailto:jcchu at rerouted.org] On Behalf Of JC Chu Sent: Monday, March 03, 2014 8:26 AM To: mika at async.caltech.edu; Rodney M. Bates Cc: ^M3DEVEL Subject: EXT:Re: [M3devel] REFANY-keyed tables? > Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). >>> 5. But then y still has the old value: st(y) = s. >> With a correctly implemented GC (which we have), step 5 can't happen. > If x and y point to the same object and you don't assign to them, they keep pointing to the same object. Hmm... I'll glad this is the case, but I don't see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? - JC Chu ---------------------------------------- > To: jcchu at acm.org > CC: mika at async.caltech.edu; m3devel at elegosoft.com > To: rodney_bates at lcwb.coop > Subject: Re: [M3devel] REFANY-keyed tables? > Date: Sun, 2 Mar 2014 12:17:41 -0800 > From: mika at async.caltech.edu > > > Right, right. > > Another way of seeing it is that if st(x) = st(y) then x and y are > pointing to the same object. The language specification does talk > about memory, albeit abstractly. > > If x and y point to the same object and you don't assign to them, they > keep pointing to the same object. That is the language semantics, and > yes, by The Green Book I mean Systems Programming with Modula-3. > > And yeah whatever the implementation does has to respect the language > semantics. If the GC wants to change the bit representation of x then > it has to change the bit representation of y in a way such that your > program will always see x = y. Note that it is NOT literally required > that the bit representation of x always equals the bit representation > of y. But I do believe the GC accomplishes x = y by ensuring that > their bit representations are always equal in any state where they may > be checked by your program. > > Another way of looking at this is to consider references in the > language as products of NEW. Every reference to a particular > evaluation of NEW always points to the same thing. If NEW has only > been evaluated once in your program, there can only be two REFANYs: > NIL and the result of that NEW. Those are the language semantics. And > of course the implementation has to go to some effort to ensure this > property holds even as it fiddles with the bit representations of the > two REFANYs. (NIL's bit representation is *probably* constant, but it > doesn't have to be...) > > Mika > > "Rodney M. Bates" writes: >> >> >>On 03/02/2014 09:00 AM, JC Chu wrote: >>>> You can't apply ^ to REFANY. >>> >>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>> >>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>> 3. Then the GC creates a copy s' of s. >>> 4. Then the GC updates x so that st(x) = s'. >>> 5. But then y still has the old value: st(y) = s. >> >>With a correctly implemented GC (which we have), step 5 can't happen. >>The GC will prevent any use of y by a running mutator thread until it >>(the GC) has updated y as well as x, so x = y again. My questions to >>Tony were about how the >>M3 GC accomplishes this, and it does. >> >>The motivatation for not giving REFANY a succeeding Hash is that, >>after the updates, x = y # . >>This would make a hash table fail, even if x = y works as defined. >>Mika is right, as long as you stay in the safe subset of the language. >>You simply can't write a hash function on a REFANY at all. >> >>Somebody could, however, declare the module with the Hash function >>UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if >>the sizes were not the same), and return that or something derived from it. >> >>It is never feasible in any language to define everything that can >>happen, when type-unsafe techniques are used. That inevitably gets >>into implementation details, which we often make assumptions about >>rather cavalierly. Part of the wisdom of Modula-3 is that it clearly >>defines what the safe subset is, then equally clearly defines the >>semantics of that,, without getting into implementation. >> >>I was careless about glossing over the safe/unsafe distinction. >> >>> >>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x >>> is stored in a container for REFANY, then a membership check for x >>> using y will fail, >> because it can only be based on Refany.Equal. (If T.Equal is used >> then we won't have this problem.) >>> >>>> REFANY behaves the way the Green Book says it does. >>> >>> You mean Systems Programming with Modula-3? >>> >>> - JC Chu >>> >>> -----Original Message----- >>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>> Sent: Sunday, March 2, 2014 21:03 >>> To: JC Chu; rodney_bates at lcwb.coop >>> Cc: m3devel at elegosoft.com >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> >>> >>> I just want to make an observation... >>> >>> REFANY behaves the way the Green Book says it does. There's not a >>> word in there about concurrent garbage collectors or bit-pattern >>> representations of RE >>FANY. >>> >>> If a, b : REFANY and a = b then a and b point to the same object. >>> >>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>> (Not because the garbage collector is implemented one way or >>> another.) >>> >>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>> >>> The rest is implementation... >>> >>> I'm not saying there isn't a lot of implementation, or that the >>> implementation doesn't have to get clever about some things, but you >>> really don't need to >> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>> >>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>> It defeats the purpose of REFANY. >>> >>> If you MUST hash a whole bunch of objects that have being REFANY as >>> their only thing in common I'd suggest using TYPECODE and >>> registering hash procedures >> for each type you're interested in. This is a simple enough thing >>that Modula-3's runtime "introspection" facilities more than suffice. >>(Those facilitie s are more limited than Java's, for mostly good >>reasons.) >>> >>> Mika >>> From jcchu at acm.org Tue Mar 4 01:04:16 2014 From: jcchu at acm.org (JC Chu) Date: Tue, 4 Mar 2014 08:04:16 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <0BB8FA59C2932741A3A2941A8B9D8BFF925EE54F@ATLEX04-SRV.SCIRES.LOCAL> References: <0BB8FA59C2932741A3A2941A8B9D8BFF925EE54F@ATLEX04-SRV.SCIRES.LOCAL> Message-ID: > For the CM3 implementation, Anthony Hosking has worked the GC "magic" to make sure the X=Y property holds true, so he is most qualified to comment on how it's done. Off the top of my head I don't recall if this is done by suspending threads or if the GC doesn't allow movement of these referents while the references are in use. I know I have a copy of Anthony's paper somewhere, so if you are curious, let me know and I can send you the link. Thanks, but I guess I?ll need to learn some basics about garbage collection before reading it. For the moment I?m happy that the GC just works as expected. ? JC Chu -----Original Message----- From: Coleburn, Randy [mailto:rcolebur at SCIRES.COM] Sent: Tuesday, March 4, 2014 6:57 To: JC Chu; mika at async.caltech.edu; Rodney M. Bates Cc: m3devel at elegosoft.com Subject: RE: [M3devel] REFANY-keyed tables? JC: My understanding is that this is NOT an implementation-specific property, but rather it is a language property/requirement that all implementations must meet. *If* the implementation's GC were to move things around, it would have to update *all* references to point to the new location BEFORE allowing any thread to use the reference, thereby preventing incorrect use of the old location. So, if X and Y are references AND if X=Y (i.e. they reference the same thing), the implementation must ensure X=Y remains valid for all threads of execution even if the GC chooses to relocate the referents. For the CM3 implementation, Anthony Hosking has worked the GC "magic" to make sure the X=Y property holds true, so he is most qualified to comment on how it's done. Off the top of my head I don't recall if this is done by suspending threads or if the GC doesn't allow movement of these referents while the references are in use. I know I have a copy of Anthony's paper somewhere, so if you are curious, let me know and I can send you the link. Thanks, Randy Coleburn -----Original Message----- From: JC Chu [mailto:jcchu at rerouted.org] On Behalf Of JC Chu Sent: Monday, March 03, 2014 8:26 AM To: mika at async.caltech.edu; Rodney M. Bates Cc: ^M3DEVEL Subject: EXT:Re: [M3devel] REFANY-keyed tables? > Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). >>> 5. But then y still has the old value: st(y) = s. >> With a correctly implemented GC (which we have), step 5 can't happen. > If x and y point to the same object and you don't assign to them, they keep pointing to the same object. Hmm... I'll glad this is the case, but I don't see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? - JC Chu ---------------------------------------- > To: jcchu at acm.org > CC: mika at async.caltech.edu; m3devel at elegosoft.com > To: rodney_bates at lcwb.coop > Subject: Re: [M3devel] REFANY-keyed tables? > Date: Sun, 2 Mar 2014 12:17:41 -0800 > From: mika at async.caltech.edu > > > Right, right. > > Another way of seeing it is that if st(x) = st(y) then x and y are > pointing to the same object. The language specification does talk > about memory, albeit abstractly. > > If x and y point to the same object and you don't assign to them, they > keep pointing to the same object. That is the language semantics, and > yes, by The Green Book I mean Systems Programming with Modula-3. > > And yeah whatever the implementation does has to respect the language > semantics. If the GC wants to change the bit representation of x then > it has to change the bit representation of y in a way such that your > program will always see x = y. Note that it is NOT literally required > that the bit representation of x always equals the bit representation > of y. But I do believe the GC accomplishes x = y by ensuring that > their bit representations are always equal in any state where they may > be checked by your program. > > Another way of looking at this is to consider references in the > language as products of NEW. Every reference to a particular > evaluation of NEW always points to the same thing. If NEW has only > been evaluated once in your program, there can only be two REFANYs: > NIL and the result of that NEW. Those are the language semantics. And > of course the implementation has to go to some effort to ensure this > property holds even as it fiddles with the bit representations of the > two REFANYs. (NIL's bit representation is *probably* constant, but it > doesn't have to be...) > > Mika > > "Rodney M. Bates" writes: >> >> >>On 03/02/2014 09:00 AM, JC Chu wrote: >>>> You can't apply ^ to REFANY. >>> >>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>> >>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>> 3. Then the GC creates a copy s' of s. >>> 4. Then the GC updates x so that st(x) = s'. >>> 5. But then y still has the old value: st(y) = s. >> >>With a correctly implemented GC (which we have), step 5 can't happen. >>The GC will prevent any use of y by a running mutator thread until it >>(the GC) has updated y as well as x, so x = y again. My questions to >>Tony were about how the >>M3 GC accomplishes this, and it does. >> >>The motivatation for not giving REFANY a succeeding Hash is that, >>after the updates, x = y # . >>This would make a hash table fail, even if x = y works as defined. >>Mika is right, as long as you stay in the safe subset of the language. >>You simply can't write a hash function on a REFANY at all. >> >>Somebody could, however, declare the module with the Hash function >>UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if >>the sizes were not the same), and return that or something derived from it. >> >>It is never feasible in any language to define everything that can >>happen, when type-unsafe techniques are used. That inevitably gets >>into implementation details, which we often make assumptions about >>rather cavalierly. Part of the wisdom of Modula-3 is that it clearly >>defines what the safe subset is, then equally clearly defines the >>semantics of that,, without getting into implementation. >> >>I was careless about glossing over the safe/unsafe distinction. >> >>> >>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x >>> is stored in a container for REFANY, then a membership check for x >>> using y will fail, >> because it can only be based on Refany.Equal. (If T.Equal is used >> then we won't have this problem.) >>> >>>> REFANY behaves the way the Green Book says it does. >>> >>> You mean Systems Programming with Modula-3? >>> >>> - JC Chu >>> >>> -----Original Message----- >>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>> Sent: Sunday, March 2, 2014 21:03 >>> To: JC Chu; rodney_bates at lcwb.coop >>> Cc: m3devel at elegosoft.com >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> >>> >>> I just want to make an observation... >>> >>> REFANY behaves the way the Green Book says it does. There's not a >>> word in there about concurrent garbage collectors or bit-pattern >>> representations of RE >>FANY. >>> >>> If a, b : REFANY and a = b then a and b point to the same object. >>> >>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>> (Not because the garbage collector is implemented one way or >>> another.) >>> >>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>> >>> The rest is implementation... >>> >>> I'm not saying there isn't a lot of implementation, or that the >>> implementation doesn't have to get clever about some things, but you >>> really don't need to >> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>> >>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>> It defeats the purpose of REFANY. >>> >>> If you MUST hash a whole bunch of objects that have being REFANY as >>> their only thing in common I'd suggest using TYPECODE and >>> registering hash procedures >> for each type you're interested in. This is a simple enough thing >>that Modula-3's runtime "introspection" facilities more than suffice. >>(Those facilitie s are more limited than Java's, for mostly good >>reasons.) >>> >>> Mika >>> From mika at async.caltech.edu Tue Mar 4 01:33:02 2014 From: mika at async.caltech.edu (mika at async.caltech.edu) Date: Mon, 03 Mar 2014 16:33:02 -0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop> <20140302201741.C42E71A2094@async.async.caltech.edu> <3E55E8A6-AF96-451D-9E94-3645DD4F050C@purdue.edu> Message-ID: <20140304003302.7B67E1A2094@async.async.caltech.edu> Here is the simple way of thinking about garbage collectors: The only thing that your program might do differently if you turn off the garbage collector is run out of memory sooner. Nothing else about its behavior should change---any change would point to a mistake in the implementation of the garbage collector. Mika JC Chu writes: >I see. So it is expected for garbage collectors to ensure that, as Tony = >put it, =E2=80=98every reference to a particular evaluation of NEW = >always points to the same thing=E2=80=99. > >=E2=80=94 JC Chu > >-----Original Message----- >From: Antony Hosking [mailto:hosking at purdue.edu]=20 >Sent: Monday, March 3, 2014 22:58 >To: JC Chu >Cc: mika at async.caltech.edu; Rodney M. Bates; ^M3DEVEL >Subject: Re: [M3devel] REFANY-keyed tables? > >The GC maintains what is called a to-space invariant: all mutators are = >switched to the copy space before the collector starts moving objects. = >The read barrier ensures that mutators can never see old space objects. = >But as Mika notes, this is an implementation detail that ensures the = >language semantics in which reference equality just works as you would = >expect. The same is true of Java or any garbage collected language. > >Sent from my iPad > >On Mar 3, 2014, at 8:25 AM, JC Chu wrote: > >>> Another way of seeing it is that if st(x) =3D st(y) then x and y are = >pointing to the same object. >>=20 >>=20 >> Well the language definition does state that st(x) =3D st(y) implies x = >=3D y (and the opposite implication is obvious). >>=20 >>=20 >>>>> 5. But then y still has the old value: st(y) =3D s. >>=20 >>=20 >>>> With a correctly implemented GC (which we have), step 5 can't = >happen. >>=20 >>=20 >>> If x and y point to the same object and you don't assign to them, = >they keep pointing to the same object. >>=20 >>=20 >> Hmm... I=E2=80=99ll glad this is the case, but I don=E2=80=99t see = >how it follows from the language definition alone. I mean the GC itself = >changes things on its own, without my having to assign to anything. If = >some poor GC did let step 5 happen and we have x # y and st(x) # st(y), = >it is still consistent with x =3D y iff st(x) =3D st(y). So this nice = >property is implementation-specific after all... Or did I miss anything = >from the language definition? >>=20 >> =E2=80=94 JC Chu >>=20 >>=20 >> ---------------------------------------- >>> To: jcchu at acm.org >>> CC: mika at async.caltech.edu; m3devel at elegosoft.com >>> To: rodney_bates at lcwb.coop >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> Date: Sun, 2 Mar 2014 12:17:41 -0800 >>> From: mika at async.caltech.edu >>>=20 >>>=20 >>> Right, right. >>>=20 >>> Another way of seeing it is that if st(x) =3D st(y) then x and y are=20 >>> pointing to the same object. The language specification does talk=20 >>> about memory, albeit abstractly. >>>=20 >>> If x and y point to the same object and you don't assign to them,=20 >>> they keep pointing to the same object. That is the language=20 >>> semantics, and yes, by The Green Book I mean Systems Programming with = >Modula-3. >>>=20 >>> And yeah whatever the implementation does has to respect the language = > >>> semantics. If the GC wants to change the bit representation of x then = > >>> it has to change the bit representation of y in a way such that your=20 >>> program will always see x =3D y. Note that it is NOT literally = >required=20 >>> that the bit representation of x always equals the bit representation = > >>> of y. But I do believe the GC accomplishes x =3D y by ensuring that=20 >>> their bit representations are always equal in any state where they=20 >>> may be checked by your program. >>>=20 >>> Another way of looking at this is to consider references in the=20 >>> language as products of NEW. Every reference to a particular=20 >>> evaluation of NEW always points to the same thing. If NEW has only=20 >>> been evaluated once in your program, there can only be two REFANYs:=20 >>> NIL and the result of that NEW. Those are the language semantics. And = > >>> of course the implementation has to go to some effort to ensure this=20 >>> property holds even as it fiddles with the bit representations of the = > >>> two REFANYs. (NIL's bit representation is *probably* constant, but it = > >>> doesn't have to be...) >>>=20 >>> Mika >>>=20 >>> "Rodney M. Bates" writes: >>>>=20 >>>>=20 >>>> On 03/02/2014 09:00 AM, JC Chu wrote: >>>>>> You can't apply ^ to REFANY. >>>>>=20 >>>>> That was a mistake on my part. Let me rephrase my worry as follows, = >where st(r) denotes the storage location pointed to by the reference r. >>>>>=20 >>>>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>>>> 2. Initially, x =3D y # NIL and st(x) =3D st(y) =3D s. >>>>> 3. Then the GC creates a copy s' of s. >>>>> 4. Then the GC updates x so that st(x) =3D s'. >>>>> 5. But then y still has the old value: st(y) =3D s. >>>>=20 >>>> With a correctly implemented GC (which we have), step 5 can't=20 >>>> happen. The GC will prevent any use of y by a running mutator thread = > >>>> until it (the GC) has updated y as well as x, so x =3D y again. My=20 >>>> questions to Tony were about how the >>>> M3 GC accomplishes this, and it does. >>>>=20 >>>> The motivatation for not giving REFANY a succeeding Hash is that,=20 >>>> after the updates, x =3D y # move>.=20 >>>> This would make a hash table fail, even if x =3D y works as defined. = > >>>> Mika is right, as long as you stay in the safe subset of the=20 >>>> language. You simply can't write a hash function on a REFANY at all. >>>>=20 >>>> Somebody could, however, declare the module with the Hash function=20 >>>> UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if = > >>>> the sizes were not the same), and return that or something derived = >from it. >>>>=20 >>>> It is never feasible in any language to define everything that can=20 >>>> happen, when type-unsafe techniques are used. That inevitably gets=20 >>>> into implementation details, which we often make assumptions about=20 >>>> rather cavalierly. Part of the wisdom of Modula-3 is that it clearly = > >>>> defines what the safe subset is, then equally clearly defines the=20 >>>> semantics of that,, without getting into implementation. >>>>=20 >>>> I was careless about glossing over the safe/unsafe distinction. >>>>=20 >>>>>=20 >>>>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x=20 >>>>> is stored in a container for REFANY, then a membership check for x=20 >>>>> using y will fail, >>>> because it can only be based on Refany.Equal. (If T.Equal is used=20 >>>> then we won=E2=80=99t have this problem.) >>>>>=20 >>>>>> REFANY behaves the way the Green Book says it does. >>>>>=20 >>>>> You mean Systems Programming with Modula-3? >>>>>=20 >>>>> =E2=80=94 JC Chu >>>>>=20 >>>>> -----Original Message----- >>>>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>>>> Sent: Sunday, March 2, 2014 21:03 >>>>> To: JC Chu; rodney_bates at lcwb.coop >>>>> Cc: m3devel at elegosoft.com >>>>> Subject: Re: [M3devel] REFANY-keyed tables? >>>>>=20 >>>>>=20 >>>>> I just want to make an observation... >>>>>=20 >>>>> REFANY behaves the way the Green Book says it does. There's not a=20 >>>>> word in there about concurrent garbage collectors or bit-pattern=20 >>>>> representations of RE >>>> FANY. >>>>>=20 >>>>> If a, b : REFANY and a =3D b then a and b point to the same object. >>>>>=20 >>>>> You can't apply ^ to REFANY. The only thing you can do to a value = >beyond =3D is narrow it to another type. That's why there's no Hash for = >REFANY. >>>>> (Not because the garbage collector is implemented one way or=20 >>>>> another.) >>>>>=20 >>>>> Of course you can put REFANY in a list. You can make as many copies = >in as many places as you want and =3D will continue working. >>>>>=20 >>>>> The rest is implementation... >>>>>=20 >>>>> I'm not saying there isn't a lot of implementation, or that the=20 >>>>> implementation doesn't have to get clever about some things, but=20 >>>>> you really don't need to >>>> think about the implementation to know what you can and can't do = >with REFANY. It's all in the Green Book. >>>>>=20 >>>>> I definitely would not suggest messing with the garbage collector = >because you want to get something working with REFANY in a pure Modula-3 = >program. >>>>> It defeats the purpose of REFANY. >>>>>=20 >>>>> If you MUST hash a whole bunch of objects that have being REFANY as = > >>>>> their only thing in common I'd suggest using TYPECODE and=20 >>>>> registering hash procedures >>>> for each type you're interested in. This is a simple enough thing=20 >>>> that Modula-3's runtime "introspection" facilities more than=20 >>>> suffice. (Those facilitie s are more limited than Java's, for mostly = > >>>> good reasons.) >>>>>=20 >>>>> Mika >>>>> =20 From jcchu at acm.org Tue Mar 4 01:03:33 2014 From: jcchu at acm.org (JC Chu) Date: Tue, 4 Mar 2014 08:03:33 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <3E55E8A6-AF96-451D-9E94-3645DD4F050C@purdue.edu> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop> <20140302201741.C42E71A2094@async.async.caltech.edu> <3E55E8A6-AF96-451D-9E94-3645DD4F050C@purdue.edu> Message-ID: I see. So it is expected for garbage collectors to ensure that, as Tony put it, ?every reference to a particular evaluation of NEW always points to the same thing?. ? JC Chu -----Original Message----- From: Antony Hosking [mailto:hosking at purdue.edu] Sent: Monday, March 3, 2014 22:58 To: JC Chu Cc: mika at async.caltech.edu; Rodney M. Bates; ^M3DEVEL Subject: Re: [M3devel] REFANY-keyed tables? The GC maintains what is called a to-space invariant: all mutators are switched to the copy space before the collector starts moving objects. The read barrier ensures that mutators can never see old space objects. But as Mika notes, this is an implementation detail that ensures the language semantics in which reference equality just works as you would expect. The same is true of Java or any garbage collected language. Sent from my iPad On Mar 3, 2014, at 8:25 AM, JC Chu wrote: >> Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. > > > Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). > > >>>> 5. But then y still has the old value: st(y) = s. > > >>> With a correctly implemented GC (which we have), step 5 can't happen. > > >> If x and y point to the same object and you don't assign to them, they keep pointing to the same object. > > > Hmm... I?ll glad this is the case, but I don?t see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? > > ? JC Chu > > > ---------------------------------------- >> To: jcchu at acm.org >> CC: mika at async.caltech.edu; m3devel at elegosoft.com >> To: rodney_bates at lcwb.coop >> Subject: Re: [M3devel] REFANY-keyed tables? >> Date: Sun, 2 Mar 2014 12:17:41 -0800 >> From: mika at async.caltech.edu >> >> >> Right, right. >> >> Another way of seeing it is that if st(x) = st(y) then x and y are >> pointing to the same object. The language specification does talk >> about memory, albeit abstractly. >> >> If x and y point to the same object and you don't assign to them, >> they keep pointing to the same object. That is the language >> semantics, and yes, by The Green Book I mean Systems Programming with Modula-3. >> >> And yeah whatever the implementation does has to respect the language >> semantics. If the GC wants to change the bit representation of x then >> it has to change the bit representation of y in a way such that your >> program will always see x = y. Note that it is NOT literally required >> that the bit representation of x always equals the bit representation >> of y. But I do believe the GC accomplishes x = y by ensuring that >> their bit representations are always equal in any state where they >> may be checked by your program. >> >> Another way of looking at this is to consider references in the >> language as products of NEW. Every reference to a particular >> evaluation of NEW always points to the same thing. If NEW has only >> been evaluated once in your program, there can only be two REFANYs: >> NIL and the result of that NEW. Those are the language semantics. And >> of course the implementation has to go to some effort to ensure this >> property holds even as it fiddles with the bit representations of the >> two REFANYs. (NIL's bit representation is *probably* constant, but it >> doesn't have to be...) >> >> Mika >> >> "Rodney M. Bates" writes: >>> >>> >>> On 03/02/2014 09:00 AM, JC Chu wrote: >>>>> You can't apply ^ to REFANY. >>>> >>>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>>> >>>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>>> 3. Then the GC creates a copy s' of s. >>>> 4. Then the GC updates x so that st(x) = s'. >>>> 5. But then y still has the old value: st(y) = s. >>> >>> With a correctly implemented GC (which we have), step 5 can't >>> happen. The GC will prevent any use of y by a running mutator thread >>> until it (the GC) has updated y as well as x, so x = y again. My >>> questions to Tony were about how the >>> M3 GC accomplishes this, and it does. >>> >>> The motivatation for not giving REFANY a succeeding Hash is that, >>> after the updates, x = y # . >>> This would make a hash table fail, even if x = y works as defined. >>> Mika is right, as long as you stay in the safe subset of the >>> language. You simply can't write a hash function on a REFANY at all. >>> >>> Somebody could, however, declare the module with the Hash function >>> UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if >>> the sizes were not the same), and return that or something derived from it. >>> >>> It is never feasible in any language to define everything that can >>> happen, when type-unsafe techniques are used. That inevitably gets >>> into implementation details, which we often make assumptions about >>> rather cavalierly. Part of the wisdom of Modula-3 is that it clearly >>> defines what the safe subset is, then equally clearly defines the >>> semantics of that,, without getting into implementation. >>> >>> I was careless about glossing over the safe/unsafe distinction. >>> >>>> >>>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x >>>> is stored in a container for REFANY, then a membership check for x >>>> using y will fail, >>> because it can only be based on Refany.Equal. (If T.Equal is used >>> then we won?t have this problem.) >>>> >>>>> REFANY behaves the way the Green Book says it does. >>>> >>>> You mean Systems Programming with Modula-3? >>>> >>>> ? JC Chu >>>> >>>> -----Original Message----- >>>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>>> Sent: Sunday, March 2, 2014 21:03 >>>> To: JC Chu; rodney_bates at lcwb.coop >>>> Cc: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] REFANY-keyed tables? >>>> >>>> >>>> I just want to make an observation... >>>> >>>> REFANY behaves the way the Green Book says it does. There's not a >>>> word in there about concurrent garbage collectors or bit-pattern >>>> representations of RE >>> FANY. >>>> >>>> If a, b : REFANY and a = b then a and b point to the same object. >>>> >>>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>>> (Not because the garbage collector is implemented one way or >>>> another.) >>>> >>>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>>> >>>> The rest is implementation... >>>> >>>> I'm not saying there isn't a lot of implementation, or that the >>>> implementation doesn't have to get clever about some things, but >>>> you really don't need to >>> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>>> >>>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>>> It defeats the purpose of REFANY. >>>> >>>> If you MUST hash a whole bunch of objects that have being REFANY as >>>> their only thing in common I'd suggest using TYPECODE and >>>> registering hash procedures >>> for each type you're interested in. This is a simple enough thing >>> that Modula-3's runtime "introspection" facilities more than >>> suffice. (Those facilitie s are more limited than Java's, for mostly >>> good reasons.) >>>> >>>> Mika >>>> From hendrik at topoi.pooq.com Thu Mar 20 20:39:38 2014 From: hendrik at topoi.pooq.com (Hendrik Boom) Date: Thu, 20 Mar 2014 15:39:38 -0400 Subject: [M3devel] musl Message-ID: <20140320193938.GA18041@topoi.pooq.com> There's a new C library on the block. I don't know if this is at all relevant for Modula 3 implementation, but I thought i should mention it in case it is: http://www.musl-libc.org/ If nothing else, it has a different license. -- hendrik From jay.krell at cornell.edu Thu Mar 20 22:29:15 2014 From: jay.krell at cornell.edu (Jay K) Date: Thu, 20 Mar 2014 21:29:15 +0000 Subject: [M3devel] musl In-Reply-To: <20140320193938.GA18041@topoi.pooq.com> References: <20140320193938.GA18041@topoi.pooq.com> Message-ID: All of our use of the C library is from C/C++ now, not from Modula-3 directly. There is no longer C-library specific code/rewritten headers. Whatever your C compiler/flags use is what Modula-3 uses. - Jay > Date: Thu, 20 Mar 2014 15:39:38 -0400 > From: hendrik at topoi.pooq.com > To: m3devel at elegosoft.com > Subject: [M3devel] musl > > There's a new C library on the block. I don't know if this is at all > relevant for Modula 3 implementation, but I thought i should mention it > in case it is: > > http://www.musl-libc.org/ > > If nothing else, it has a different license. > > -- hendrik > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dragisha at m3w.org Sat Mar 1 19:12:36 2014 From: dragisha at m3w.org (=?utf-8?Q?Dragi=C5=A1a_Duri=C4=87?=) Date: Sat, 1 Mar 2014 19:12:36 +0100 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> Message-ID: I am not following this thread so well, but? Why do you need something like this? Maybe to use it as an argument to a C callback? On 28 Feb 2014, at 18:40, JC Chu wrote: >> ... The above technique works if you really want to simulate keying on the address (as it would be in a no-move GC environment.), which I suppose is what you wanted. > > Yes, I was indeed in need of an immutable version of REFANY. > > ? JC Chu > > -----Original Message----- > From: Rodney M. Bates [mailto:rodney_bates at lcwb.coop] > Sent: Friday, February 28, 2014 23:16 > To: m3devel at elegosoft.com > Subject: Re: [M3devel] REFANY-keyed tables? > > > > On 02/26/2014 09:28 PM, Rodney M. Bates wrote: >> >> >> On 02/26/2014 11:08 AM, JC Chu wrote: >>> Hi, >>> >>> I need a REFANY-to-INTEGER table in my program but RefIntTbl.Default is giving me runtime errors. Apparently Table(Key, Value) uses Key.Equal() and Key.Hash(), but those procedures in Refany, which is use to instantiate RefIntTbl, both raise a fatal exception. >>> >> >> The garbage collector is a (partially) compacting collector, which >> means it can move a heap object and adjust all the pointers to it, if >> it knows where they all are, which holds for some objects. So the bit >> contents of a REFANY can change. This means it is not possible to have a consistent Hash on the pointer value alone. >> >> So Refany.Hash is deliberately coded to raise this exception, to >> prevent a far more insidious bug. >> >>> I?m a bit confused since a number of REFANY-keyed tables are shipped with CM3. Is this actually the expected behavior or am I doing anything wrong? >>> >> >> Hmm, can you point out where these are? >> >> I have some pointer-keyed tables, but they use techniques like giving >> every object an object sequence number field, explicitly initialized >> when an object is allocated, and using that for the Hash function. >> But this won't work for REFANY, because it can have no fields. >> > > There is more to this. The above technique works if you really want to simulate keying on the address (as it would be in a no-move GC environment.), which I suppose is what you wanted. > > But in many cases, you might want to hash on the contents, not the address of the object, in which case, the technique used in juno-2, using actual data fields instead of an object sequence number is the right way. For example, to turn the objects into atoms. > >> So the table can only work on a narrower set of allocated object types than REFANY. >> If you need the table to hold addresses of a mixture of different >> types, you can still do that with a hierarchy of OBJECT types, but >> they will have to have a common supertype that contains whatever fields the Hash function needs for consistency. >> >> It would be possible that pointers get passed around in REFANY-typed >> (statically) variables, but it is carefully arranged that they all >> have an allocated type that has fields a Hash function can work on. >> Hash would then have to do a NARROW or TYPECASE to the type it expected. >> >> Rodney Bates >> >>> Thanks. >>> >>> ? JC Chu >>> >> >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 495 bytes Desc: Message signed with OpenPGP using GPGMail URL: From jcchu at acm.org Sun Mar 2 06:09:48 2014 From: jcchu at acm.org (JC Chu) Date: Sun, 2 Mar 2014 13:09:48 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , Message-ID: Oh I just needed to count the number of times each object has been visited, where objects a and b are considered identical iff Refany.Equal(a, b), so tagging objects with sequential integers and using instead an INTEGER-to-INTEGER table sufficed. - JC Chu ---------------------------------------- > Subject: Re: [M3devel] REFANY-keyed tables? > From: dragisha at m3w.org > Date: Sat, 1 Mar 2014 19:12:36 +0100 > CC: rodney_bates at lcwb.coop; m3devel at elegosoft.com > To: jcchu at acm.org > > I am not following this thread so well, but. Why do you need something like this? Maybe to use it as an argument to a C callback? > From mika at async.caltech.edu Sun Mar 2 14:02:43 2014 From: mika at async.caltech.edu (mika at async.caltech.edu) Date: Sun, 02 Mar 2014 05:02:43 -0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , Message-ID: <20140302130243.7BD831A2095@async.async.caltech.edu> I just want to make an observation... REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of REFANY. If a, b : REFANY and a = b then a and b point to the same object. You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. (Not because the garbage collector is implemented one way or another.) Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. The rest is implementation... I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. It defeats the purpose of REFANY. If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilities are more limited than Java's, for mostly good reasons.) Mika From jcchu at acm.org Sun Mar 2 16:00:25 2014 From: jcchu at acm.org (JC Chu) Date: Sun, 2 Mar 2014 23:00:25 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <20140302130243.7BD831A2095@async.async.caltech.edu> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> Message-ID: > You can't apply ^ to REFANY. That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. 1. x, y: REF T, where T has an equivalence relation T.Equal. 2. Initially, x = y # NIL and st(x) = st(y) = s. 3. Then the GC creates a copy s' of s. 4. Then the GC updates x so that st(x) = s'. 5. But then y still has the old value: st(y) = s. At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, because it can only be based on Refany.Equal. (If T.Equal is used then we won?t have this problem.) > REFANY behaves the way the Green Book says it does. You mean Systems Programming with Modula-3? ? JC Chu -----Original Message----- From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] Sent: Sunday, March 2, 2014 21:03 To: JC Chu; rodney_bates at lcwb.coop Cc: m3devel at elegosoft.com Subject: Re: [M3devel] REFANY-keyed tables? I just want to make an observation... REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of REFANY. If a, b : REFANY and a = b then a and b point to the same object. You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. (Not because the garbage collector is implemented one way or another.) Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. The rest is implementation... I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. It defeats the purpose of REFANY. If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilities are more limited than Java's, for mostly good reasons.) Mika From rodney_bates at lcwb.coop Sun Mar 2 20:57:08 2014 From: rodney_bates at lcwb.coop (Rodney M. Bates) Date: Sun, 02 Mar 2014 13:57:08 -0600 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> Message-ID: <53138D14.2030102@lcwb.coop> On 03/02/2014 09:00 AM, JC Chu wrote: >> You can't apply ^ to REFANY. > > That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. > > 1. x, y: REF T, where T has an equivalence relation T.Equal. > 2. Initially, x = y # NIL and st(x) = st(y) = s. > 3. Then the GC creates a copy s' of s. > 4. Then the GC updates x so that st(x) = s'. > 5. But then y still has the old value: st(y) = s. With a correctly implemented GC (which we have), step 5 can't happen. The GC will prevent any use of y by a running mutator thread until it (the GC) has updated y as well as x, so x = y again. My questions to Tony were about how the M3 GC accomplishes this, and it does. The motivatation for not giving REFANY a succeeding Hash is that, after the updates, x = y # . This would make a hash table fail, even if x = y works as defined. Mika is right, as long as you stay in the safe subset of the language. You simply can't write a hash function on a REFANY at all. Somebody could, however, declare the module with the Hash function UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if the sizes were not the same), and return that or something derived from it. It is never feasible in any language to define everything that can happen, when type-unsafe techniques are used. That inevitably gets into implementation details, which we often make assumptions about rather cavalierly. Part of the wisdom of Modula-3 is that it clearly defines what the safe subset is, then equally clearly defines the semantics of that,, without getting into implementation. I was careless about glossing over the safe/unsafe distinction. > > At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, because it can only be based on Refany.Equal. (If T.Equal is used then we won?t have this problem.) > >> REFANY behaves the way the Green Book says it does. > > You mean Systems Programming with Modula-3? > > ? JC Chu > > -----Original Message----- > From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] > Sent: Sunday, March 2, 2014 21:03 > To: JC Chu; rodney_bates at lcwb.coop > Cc: m3devel at elegosoft.com > Subject: Re: [M3devel] REFANY-keyed tables? > > > I just want to make an observation... > > REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of REFANY. > > If a, b : REFANY and a = b then a and b point to the same object. > > You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. > (Not because the garbage collector is implemented one way or another.) > > Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. > > The rest is implementation... > > I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. > > I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. > It defeats the purpose of REFANY. > > If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilities are more limited than Java's, for mostly good reasons.) > > Mika > From mika at async.caltech.edu Sun Mar 2 21:17:41 2014 From: mika at async.caltech.edu (mika at async.caltech.edu) Date: Sun, 02 Mar 2014 12:17:41 -0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <53138D14.2030102@lcwb.coop> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop> Message-ID: <20140302201741.C42E71A2094@async.async.caltech.edu> Right, right. Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. The language specification does talk about memory, albeit abstractly. If x and y point to the same object and you don't assign to them, they keep pointing to the same object. That is the language semantics, and yes, by The Green Book I mean Systems Programming with Modula-3. And yeah whatever the implementation does has to respect the language semantics. If the GC wants to change the bit representation of x then it has to change the bit representation of y in a way such that your program will always see x = y. Note that it is NOT literally required that the bit representation of x always equals the bit representation of y. But I do believe the GC accomplishes x = y by ensuring that their bit representations are always equal in any state where they may be checked by your program. Another way of looking at this is to consider references in the language as products of NEW. Every reference to a particular evaluation of NEW always points to the same thing. If NEW has only been evaluated once in your program, there can only be two REFANYs: NIL and the result of that NEW. Those are the language semantics. And of course the implementation has to go to some effort to ensure this property holds even as it fiddles with the bit representations of the two REFANYs. (NIL's bit representation is *probably* constant, but it doesn't have to be...) Mika "Rodney M. Bates" writes: > > >On 03/02/2014 09:00 AM, JC Chu wrote: >>> You can't apply ^ to REFANY. >> >> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >> >> 1. x, y: REF T, where T has an equivalence relation T.Equal. >> 2. Initially, x = y # NIL and st(x) = st(y) = s. >> 3. Then the GC creates a copy s' of s. >> 4. Then the GC updates x so that st(x) = s'. >> 5. But then y still has the old value: st(y) = s. > >With a correctly implemented GC (which we have), step 5 can't happen. The GC >will prevent any use of y by a running mutator thread until it (the GC) has >updated y as well as x, so x = y again. My questions to Tony were about how the >M3 GC accomplishes this, and it does. > >The motivatation for not giving REFANY a succeeding Hash is that, after >the updates, x = y # . This would >make a hash table fail, even if x = y works as defined. Mika is right, >as long as you stay in the safe subset of the language. You simply can't >write a hash function on a REFANY at all. > >Somebody could, however, declare the module with the Hash function UNSAFE, >LOOPHOLE the REFANY value to a Word.T (or something else, if the sizes were >not the same), and return that or something derived from it. > >It is never feasible in any language to define everything that can happen, >when type-unsafe techniques are used. That inevitably gets into implementation >details, which we often make assumptions about rather cavalierly. Part of >the wisdom of Modula-3 is that it clearly defines what the safe subset is, >then equally clearly defines the semantics of that,, without getting into >implementation. > >I was careless about glossing over the safe/unsafe distinction. > >> >> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, > because it can only be based on Refany.Equal. (If T.Equal is used then we won???t have this problem.) >> >>> REFANY behaves the way the Green Book says it does. >> >> You mean Systems Programming with Modula-3? >> >> ??? JC Chu >> >> -----Original Message----- >> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >> Sent: Sunday, March 2, 2014 21:03 >> To: JC Chu; rodney_bates at lcwb.coop >> Cc: m3devel at elegosoft.com >> Subject: Re: [M3devel] REFANY-keyed tables? >> >> >> I just want to make an observation... >> >> REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of RE >FANY. >> >> If a, b : REFANY and a = b then a and b point to the same object. >> >> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >> (Not because the garbage collector is implemented one way or another.) >> >> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >> >> The rest is implementation... >> >> I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to > think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >> >> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >> It defeats the purpose of REFANY. >> >> If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures > for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilitie >s are more limited than Java's, for mostly good reasons.) >> >> Mika >> From jcchu at acm.org Mon Mar 3 14:25:42 2014 From: jcchu at acm.org (JC Chu) Date: Mon, 3 Mar 2014 21:25:42 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <20140302201741.C42E71A2094@async.async.caltech.edu> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> , <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop>, <20140302201741.C42E71A2094@async.async.caltech.edu> Message-ID: > Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). >>> 5. But then y still has the old value: st(y) = s. >> With a correctly implemented GC (which we have), step 5 can't happen. > If x and y point to the same object and you don't assign to them, they keep pointing to the same object. Hmm... I?ll glad this is the case, but I don?t see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? ? JC Chu ---------------------------------------- > To: jcchu at acm.org > CC: mika at async.caltech.edu; m3devel at elegosoft.com > To: rodney_bates at lcwb.coop > Subject: Re: [M3devel] REFANY-keyed tables? > Date: Sun, 2 Mar 2014 12:17:41 -0800 > From: mika at async.caltech.edu > > > Right, right. > > Another way of seeing it is that if st(x) = st(y) then x and y are > pointing to the same object. The language specification does talk about > memory, albeit abstractly. > > If x and y point to the same object and you don't assign to them, they > keep pointing to the same object. That is the language semantics, > and yes, by The Green Book I mean Systems Programming with Modula-3. > > And yeah whatever the implementation does has to respect the language > semantics. If the GC wants to change the bit representation of x then it > has to change the bit representation of y in a way such that your program > will always see x = y. Note that it is NOT literally required that the > bit representation of x always equals the bit representation of y. But > I do believe the GC accomplishes x = y by ensuring that their bit > representations are always equal in any state where they may be checked > by your program. > > Another way of looking at this is to consider references in the language > as products of NEW. Every reference to a particular evaluation of NEW > always points to the same thing. If NEW has only been evaluated once > in your program, there can only be two REFANYs: NIL and the result of > that NEW. Those are the language semantics. And of course the implementation > has to go to some effort to ensure this property holds even as it fiddles > with the bit representations of the two REFANYs. (NIL's bit representation > is *probably* constant, but it doesn't have to be...) > > Mika > > "Rodney M. Bates" writes: >> >> >>On 03/02/2014 09:00 AM, JC Chu wrote: >>>> You can't apply ^ to REFANY. >>> >>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>> >>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>> 3. Then the GC creates a copy s' of s. >>> 4. Then the GC updates x so that st(x) = s'. >>> 5. But then y still has the old value: st(y) = s. >> >>With a correctly implemented GC (which we have), step 5 can't happen. The GC >>will prevent any use of y by a running mutator thread until it (the GC) has >>updated y as well as x, so x = y again. My questions to Tony were about how the >>M3 GC accomplishes this, and it does. >> >>The motivatation for not giving REFANY a succeeding Hash is that, after >>the updates, x = y # . This would >>make a hash table fail, even if x = y works as defined. Mika is right, >>as long as you stay in the safe subset of the language. You simply can't >>write a hash function on a REFANY at all. >> >>Somebody could, however, declare the module with the Hash function UNSAFE, >>LOOPHOLE the REFANY value to a Word.T (or something else, if the sizes were >>not the same), and return that or something derived from it. >> >>It is never feasible in any language to define everything that can happen, >>when type-unsafe techniques are used. That inevitably gets into implementation >>details, which we often make assumptions about rather cavalierly. Part of >>the wisdom of Modula-3 is that it clearly defines what the safe subset is, >>then equally clearly defines the semantics of that,, without getting into >>implementation. >> >>I was careless about glossing over the safe/unsafe distinction. >> >>> >>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x is stored in a container for REFANY, then a membership check for x using y will fail, >> because it can only be based on Refany.Equal. (If T.Equal is used then we won?t have this problem.) >>> >>>> REFANY behaves the way the Green Book says it does. >>> >>> You mean Systems Programming with Modula-3? >>> >>> ? JC Chu >>> >>> -----Original Message----- >>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>> Sent: Sunday, March 2, 2014 21:03 >>> To: JC Chu; rodney_bates at lcwb.coop >>> Cc: m3devel at elegosoft.com >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> >>> >>> I just want to make an observation... >>> >>> REFANY behaves the way the Green Book says it does. There's not a word in there about concurrent garbage collectors or bit-pattern representations of RE >>FANY. >>> >>> If a, b : REFANY and a = b then a and b point to the same object. >>> >>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>> (Not because the garbage collector is implemented one way or another.) >>> >>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>> >>> The rest is implementation... >>> >>> I'm not saying there isn't a lot of implementation, or that the implementation doesn't have to get clever about some things, but you really don't need to >> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>> >>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>> It defeats the purpose of REFANY. >>> >>> If you MUST hash a whole bunch of objects that have being REFANY as their only thing in common I'd suggest using TYPECODE and registering hash procedures >> for each type you're interested in. This is a simple enough thing that Modula-3's runtime "introspection" facilities more than suffice. (Those facilitie >>s are more limited than Java's, for mostly good reasons.) >>> >>> Mika >>> From rcolebur at SCIRES.COM Mon Mar 3 23:56:32 2014 From: rcolebur at SCIRES.COM (Coleburn, Randy) Date: Mon, 3 Mar 2014 22:56:32 +0000 Subject: [M3devel] REFANY-keyed tables? Message-ID: <0BB8FA59C2932741A3A2941A8B9D8BFF925EE54F@ATLEX04-SRV.SCIRES.LOCAL> JC: My understanding is that this is NOT an implementation-specific property, but rather it is a language property/requirement that all implementations must meet. *If* the implementation's GC were to move things around, it would have to update *all* references to point to the new location BEFORE allowing any thread to use the reference, thereby preventing incorrect use of the old location. So, if X and Y are references AND if X=Y (i.e. they reference the same thing), the implementation must ensure X=Y remains valid for all threads of execution even if the GC chooses to relocate the referents. For the CM3 implementation, Anthony Hosking has worked the GC "magic" to make sure the X=Y property holds true, so he is most qualified to comment on how it's done. Off the top of my head I don't recall if this is done by suspending threads or if the GC doesn't allow movement of these referents while the references are in use. I know I have a copy of Anthony's paper somewhere, so if you are curious, let me know and I can send you the link. Thanks, Randy Coleburn -----Original Message----- From: JC Chu [mailto:jcchu at rerouted.org] On Behalf Of JC Chu Sent: Monday, March 03, 2014 8:26 AM To: mika at async.caltech.edu; Rodney M. Bates Cc: ^M3DEVEL Subject: EXT:Re: [M3devel] REFANY-keyed tables? > Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). >>> 5. But then y still has the old value: st(y) = s. >> With a correctly implemented GC (which we have), step 5 can't happen. > If x and y point to the same object and you don't assign to them, they keep pointing to the same object. Hmm... I'll glad this is the case, but I don't see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? - JC Chu ---------------------------------------- > To: jcchu at acm.org > CC: mika at async.caltech.edu; m3devel at elegosoft.com > To: rodney_bates at lcwb.coop > Subject: Re: [M3devel] REFANY-keyed tables? > Date: Sun, 2 Mar 2014 12:17:41 -0800 > From: mika at async.caltech.edu > > > Right, right. > > Another way of seeing it is that if st(x) = st(y) then x and y are > pointing to the same object. The language specification does talk > about memory, albeit abstractly. > > If x and y point to the same object and you don't assign to them, they > keep pointing to the same object. That is the language semantics, and > yes, by The Green Book I mean Systems Programming with Modula-3. > > And yeah whatever the implementation does has to respect the language > semantics. If the GC wants to change the bit representation of x then > it has to change the bit representation of y in a way such that your > program will always see x = y. Note that it is NOT literally required > that the bit representation of x always equals the bit representation > of y. But I do believe the GC accomplishes x = y by ensuring that > their bit representations are always equal in any state where they may > be checked by your program. > > Another way of looking at this is to consider references in the > language as products of NEW. Every reference to a particular > evaluation of NEW always points to the same thing. If NEW has only > been evaluated once in your program, there can only be two REFANYs: > NIL and the result of that NEW. Those are the language semantics. And > of course the implementation has to go to some effort to ensure this > property holds even as it fiddles with the bit representations of the > two REFANYs. (NIL's bit representation is *probably* constant, but it > doesn't have to be...) > > Mika > > "Rodney M. Bates" writes: >> >> >>On 03/02/2014 09:00 AM, JC Chu wrote: >>>> You can't apply ^ to REFANY. >>> >>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>> >>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>> 3. Then the GC creates a copy s' of s. >>> 4. Then the GC updates x so that st(x) = s'. >>> 5. But then y still has the old value: st(y) = s. >> >>With a correctly implemented GC (which we have), step 5 can't happen. >>The GC will prevent any use of y by a running mutator thread until it >>(the GC) has updated y as well as x, so x = y again. My questions to >>Tony were about how the >>M3 GC accomplishes this, and it does. >> >>The motivatation for not giving REFANY a succeeding Hash is that, >>after the updates, x = y # . >>This would make a hash table fail, even if x = y works as defined. >>Mika is right, as long as you stay in the safe subset of the language. >>You simply can't write a hash function on a REFANY at all. >> >>Somebody could, however, declare the module with the Hash function >>UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if >>the sizes were not the same), and return that or something derived from it. >> >>It is never feasible in any language to define everything that can >>happen, when type-unsafe techniques are used. That inevitably gets >>into implementation details, which we often make assumptions about >>rather cavalierly. Part of the wisdom of Modula-3 is that it clearly >>defines what the safe subset is, then equally clearly defines the >>semantics of that,, without getting into implementation. >> >>I was careless about glossing over the safe/unsafe distinction. >> >>> >>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x >>> is stored in a container for REFANY, then a membership check for x >>> using y will fail, >> because it can only be based on Refany.Equal. (If T.Equal is used >> then we won't have this problem.) >>> >>>> REFANY behaves the way the Green Book says it does. >>> >>> You mean Systems Programming with Modula-3? >>> >>> - JC Chu >>> >>> -----Original Message----- >>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>> Sent: Sunday, March 2, 2014 21:03 >>> To: JC Chu; rodney_bates at lcwb.coop >>> Cc: m3devel at elegosoft.com >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> >>> >>> I just want to make an observation... >>> >>> REFANY behaves the way the Green Book says it does. There's not a >>> word in there about concurrent garbage collectors or bit-pattern >>> representations of RE >>FANY. >>> >>> If a, b : REFANY and a = b then a and b point to the same object. >>> >>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>> (Not because the garbage collector is implemented one way or >>> another.) >>> >>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>> >>> The rest is implementation... >>> >>> I'm not saying there isn't a lot of implementation, or that the >>> implementation doesn't have to get clever about some things, but you >>> really don't need to >> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>> >>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>> It defeats the purpose of REFANY. >>> >>> If you MUST hash a whole bunch of objects that have being REFANY as >>> their only thing in common I'd suggest using TYPECODE and >>> registering hash procedures >> for each type you're interested in. This is a simple enough thing >>that Modula-3's runtime "introspection" facilities more than suffice. >>(Those facilitie s are more limited than Java's, for mostly good >>reasons.) >>> >>> Mika >>> From jcchu at acm.org Tue Mar 4 01:04:16 2014 From: jcchu at acm.org (JC Chu) Date: Tue, 4 Mar 2014 08:04:16 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <0BB8FA59C2932741A3A2941A8B9D8BFF925EE54F@ATLEX04-SRV.SCIRES.LOCAL> References: <0BB8FA59C2932741A3A2941A8B9D8BFF925EE54F@ATLEX04-SRV.SCIRES.LOCAL> Message-ID: > For the CM3 implementation, Anthony Hosking has worked the GC "magic" to make sure the X=Y property holds true, so he is most qualified to comment on how it's done. Off the top of my head I don't recall if this is done by suspending threads or if the GC doesn't allow movement of these referents while the references are in use. I know I have a copy of Anthony's paper somewhere, so if you are curious, let me know and I can send you the link. Thanks, but I guess I?ll need to learn some basics about garbage collection before reading it. For the moment I?m happy that the GC just works as expected. ? JC Chu -----Original Message----- From: Coleburn, Randy [mailto:rcolebur at SCIRES.COM] Sent: Tuesday, March 4, 2014 6:57 To: JC Chu; mika at async.caltech.edu; Rodney M. Bates Cc: m3devel at elegosoft.com Subject: RE: [M3devel] REFANY-keyed tables? JC: My understanding is that this is NOT an implementation-specific property, but rather it is a language property/requirement that all implementations must meet. *If* the implementation's GC were to move things around, it would have to update *all* references to point to the new location BEFORE allowing any thread to use the reference, thereby preventing incorrect use of the old location. So, if X and Y are references AND if X=Y (i.e. they reference the same thing), the implementation must ensure X=Y remains valid for all threads of execution even if the GC chooses to relocate the referents. For the CM3 implementation, Anthony Hosking has worked the GC "magic" to make sure the X=Y property holds true, so he is most qualified to comment on how it's done. Off the top of my head I don't recall if this is done by suspending threads or if the GC doesn't allow movement of these referents while the references are in use. I know I have a copy of Anthony's paper somewhere, so if you are curious, let me know and I can send you the link. Thanks, Randy Coleburn -----Original Message----- From: JC Chu [mailto:jcchu at rerouted.org] On Behalf Of JC Chu Sent: Monday, March 03, 2014 8:26 AM To: mika at async.caltech.edu; Rodney M. Bates Cc: ^M3DEVEL Subject: EXT:Re: [M3devel] REFANY-keyed tables? > Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). >>> 5. But then y still has the old value: st(y) = s. >> With a correctly implemented GC (which we have), step 5 can't happen. > If x and y point to the same object and you don't assign to them, they keep pointing to the same object. Hmm... I'll glad this is the case, but I don't see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? - JC Chu ---------------------------------------- > To: jcchu at acm.org > CC: mika at async.caltech.edu; m3devel at elegosoft.com > To: rodney_bates at lcwb.coop > Subject: Re: [M3devel] REFANY-keyed tables? > Date: Sun, 2 Mar 2014 12:17:41 -0800 > From: mika at async.caltech.edu > > > Right, right. > > Another way of seeing it is that if st(x) = st(y) then x and y are > pointing to the same object. The language specification does talk > about memory, albeit abstractly. > > If x and y point to the same object and you don't assign to them, they > keep pointing to the same object. That is the language semantics, and > yes, by The Green Book I mean Systems Programming with Modula-3. > > And yeah whatever the implementation does has to respect the language > semantics. If the GC wants to change the bit representation of x then > it has to change the bit representation of y in a way such that your > program will always see x = y. Note that it is NOT literally required > that the bit representation of x always equals the bit representation > of y. But I do believe the GC accomplishes x = y by ensuring that > their bit representations are always equal in any state where they may > be checked by your program. > > Another way of looking at this is to consider references in the > language as products of NEW. Every reference to a particular > evaluation of NEW always points to the same thing. If NEW has only > been evaluated once in your program, there can only be two REFANYs: > NIL and the result of that NEW. Those are the language semantics. And > of course the implementation has to go to some effort to ensure this > property holds even as it fiddles with the bit representations of the > two REFANYs. (NIL's bit representation is *probably* constant, but it > doesn't have to be...) > > Mika > > "Rodney M. Bates" writes: >> >> >>On 03/02/2014 09:00 AM, JC Chu wrote: >>>> You can't apply ^ to REFANY. >>> >>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>> >>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>> 3. Then the GC creates a copy s' of s. >>> 4. Then the GC updates x so that st(x) = s'. >>> 5. But then y still has the old value: st(y) = s. >> >>With a correctly implemented GC (which we have), step 5 can't happen. >>The GC will prevent any use of y by a running mutator thread until it >>(the GC) has updated y as well as x, so x = y again. My questions to >>Tony were about how the >>M3 GC accomplishes this, and it does. >> >>The motivatation for not giving REFANY a succeeding Hash is that, >>after the updates, x = y # . >>This would make a hash table fail, even if x = y works as defined. >>Mika is right, as long as you stay in the safe subset of the language. >>You simply can't write a hash function on a REFANY at all. >> >>Somebody could, however, declare the module with the Hash function >>UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if >>the sizes were not the same), and return that or something derived from it. >> >>It is never feasible in any language to define everything that can >>happen, when type-unsafe techniques are used. That inevitably gets >>into implementation details, which we often make assumptions about >>rather cavalierly. Part of the wisdom of Modula-3 is that it clearly >>defines what the safe subset is, then equally clearly defines the >>semantics of that,, without getting into implementation. >> >>I was careless about glossing over the safe/unsafe distinction. >> >>> >>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x >>> is stored in a container for REFANY, then a membership check for x >>> using y will fail, >> because it can only be based on Refany.Equal. (If T.Equal is used >> then we won't have this problem.) >>> >>>> REFANY behaves the way the Green Book says it does. >>> >>> You mean Systems Programming with Modula-3? >>> >>> - JC Chu >>> >>> -----Original Message----- >>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>> Sent: Sunday, March 2, 2014 21:03 >>> To: JC Chu; rodney_bates at lcwb.coop >>> Cc: m3devel at elegosoft.com >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> >>> >>> I just want to make an observation... >>> >>> REFANY behaves the way the Green Book says it does. There's not a >>> word in there about concurrent garbage collectors or bit-pattern >>> representations of RE >>FANY. >>> >>> If a, b : REFANY and a = b then a and b point to the same object. >>> >>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>> (Not because the garbage collector is implemented one way or >>> another.) >>> >>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>> >>> The rest is implementation... >>> >>> I'm not saying there isn't a lot of implementation, or that the >>> implementation doesn't have to get clever about some things, but you >>> really don't need to >> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>> >>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>> It defeats the purpose of REFANY. >>> >>> If you MUST hash a whole bunch of objects that have being REFANY as >>> their only thing in common I'd suggest using TYPECODE and >>> registering hash procedures >> for each type you're interested in. This is a simple enough thing >>that Modula-3's runtime "introspection" facilities more than suffice. >>(Those facilitie s are more limited than Java's, for mostly good >>reasons.) >>> >>> Mika >>> From mika at async.caltech.edu Tue Mar 4 01:33:02 2014 From: mika at async.caltech.edu (mika at async.caltech.edu) Date: Mon, 03 Mar 2014 16:33:02 -0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop> <20140302201741.C42E71A2094@async.async.caltech.edu> <3E55E8A6-AF96-451D-9E94-3645DD4F050C@purdue.edu> Message-ID: <20140304003302.7B67E1A2094@async.async.caltech.edu> Here is the simple way of thinking about garbage collectors: The only thing that your program might do differently if you turn off the garbage collector is run out of memory sooner. Nothing else about its behavior should change---any change would point to a mistake in the implementation of the garbage collector. Mika JC Chu writes: >I see. So it is expected for garbage collectors to ensure that, as Tony = >put it, =E2=80=98every reference to a particular evaluation of NEW = >always points to the same thing=E2=80=99. > >=E2=80=94 JC Chu > >-----Original Message----- >From: Antony Hosking [mailto:hosking at purdue.edu]=20 >Sent: Monday, March 3, 2014 22:58 >To: JC Chu >Cc: mika at async.caltech.edu; Rodney M. Bates; ^M3DEVEL >Subject: Re: [M3devel] REFANY-keyed tables? > >The GC maintains what is called a to-space invariant: all mutators are = >switched to the copy space before the collector starts moving objects. = >The read barrier ensures that mutators can never see old space objects. = >But as Mika notes, this is an implementation detail that ensures the = >language semantics in which reference equality just works as you would = >expect. The same is true of Java or any garbage collected language. > >Sent from my iPad > >On Mar 3, 2014, at 8:25 AM, JC Chu wrote: > >>> Another way of seeing it is that if st(x) =3D st(y) then x and y are = >pointing to the same object. >>=20 >>=20 >> Well the language definition does state that st(x) =3D st(y) implies x = >=3D y (and the opposite implication is obvious). >>=20 >>=20 >>>>> 5. But then y still has the old value: st(y) =3D s. >>=20 >>=20 >>>> With a correctly implemented GC (which we have), step 5 can't = >happen. >>=20 >>=20 >>> If x and y point to the same object and you don't assign to them, = >they keep pointing to the same object. >>=20 >>=20 >> Hmm... I=E2=80=99ll glad this is the case, but I don=E2=80=99t see = >how it follows from the language definition alone. I mean the GC itself = >changes things on its own, without my having to assign to anything. If = >some poor GC did let step 5 happen and we have x # y and st(x) # st(y), = >it is still consistent with x =3D y iff st(x) =3D st(y). So this nice = >property is implementation-specific after all... Or did I miss anything = >from the language definition? >>=20 >> =E2=80=94 JC Chu >>=20 >>=20 >> ---------------------------------------- >>> To: jcchu at acm.org >>> CC: mika at async.caltech.edu; m3devel at elegosoft.com >>> To: rodney_bates at lcwb.coop >>> Subject: Re: [M3devel] REFANY-keyed tables? >>> Date: Sun, 2 Mar 2014 12:17:41 -0800 >>> From: mika at async.caltech.edu >>>=20 >>>=20 >>> Right, right. >>>=20 >>> Another way of seeing it is that if st(x) =3D st(y) then x and y are=20 >>> pointing to the same object. The language specification does talk=20 >>> about memory, albeit abstractly. >>>=20 >>> If x and y point to the same object and you don't assign to them,=20 >>> they keep pointing to the same object. That is the language=20 >>> semantics, and yes, by The Green Book I mean Systems Programming with = >Modula-3. >>>=20 >>> And yeah whatever the implementation does has to respect the language = > >>> semantics. If the GC wants to change the bit representation of x then = > >>> it has to change the bit representation of y in a way such that your=20 >>> program will always see x =3D y. Note that it is NOT literally = >required=20 >>> that the bit representation of x always equals the bit representation = > >>> of y. But I do believe the GC accomplishes x =3D y by ensuring that=20 >>> their bit representations are always equal in any state where they=20 >>> may be checked by your program. >>>=20 >>> Another way of looking at this is to consider references in the=20 >>> language as products of NEW. Every reference to a particular=20 >>> evaluation of NEW always points to the same thing. If NEW has only=20 >>> been evaluated once in your program, there can only be two REFANYs:=20 >>> NIL and the result of that NEW. Those are the language semantics. And = > >>> of course the implementation has to go to some effort to ensure this=20 >>> property holds even as it fiddles with the bit representations of the = > >>> two REFANYs. (NIL's bit representation is *probably* constant, but it = > >>> doesn't have to be...) >>>=20 >>> Mika >>>=20 >>> "Rodney M. Bates" writes: >>>>=20 >>>>=20 >>>> On 03/02/2014 09:00 AM, JC Chu wrote: >>>>>> You can't apply ^ to REFANY. >>>>>=20 >>>>> That was a mistake on my part. Let me rephrase my worry as follows, = >where st(r) denotes the storage location pointed to by the reference r. >>>>>=20 >>>>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>>>> 2. Initially, x =3D y # NIL and st(x) =3D st(y) =3D s. >>>>> 3. Then the GC creates a copy s' of s. >>>>> 4. Then the GC updates x so that st(x) =3D s'. >>>>> 5. But then y still has the old value: st(y) =3D s. >>>>=20 >>>> With a correctly implemented GC (which we have), step 5 can't=20 >>>> happen. The GC will prevent any use of y by a running mutator thread = > >>>> until it (the GC) has updated y as well as x, so x =3D y again. My=20 >>>> questions to Tony were about how the >>>> M3 GC accomplishes this, and it does. >>>>=20 >>>> The motivatation for not giving REFANY a succeeding Hash is that,=20 >>>> after the updates, x =3D y # move>.=20 >>>> This would make a hash table fail, even if x =3D y works as defined. = > >>>> Mika is right, as long as you stay in the safe subset of the=20 >>>> language. You simply can't write a hash function on a REFANY at all. >>>>=20 >>>> Somebody could, however, declare the module with the Hash function=20 >>>> UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if = > >>>> the sizes were not the same), and return that or something derived = >from it. >>>>=20 >>>> It is never feasible in any language to define everything that can=20 >>>> happen, when type-unsafe techniques are used. That inevitably gets=20 >>>> into implementation details, which we often make assumptions about=20 >>>> rather cavalierly. Part of the wisdom of Modula-3 is that it clearly = > >>>> defines what the safe subset is, then equally clearly defines the=20 >>>> semantics of that,, without getting into implementation. >>>>=20 >>>> I was careless about glossing over the safe/unsafe distinction. >>>>=20 >>>>>=20 >>>>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x=20 >>>>> is stored in a container for REFANY, then a membership check for x=20 >>>>> using y will fail, >>>> because it can only be based on Refany.Equal. (If T.Equal is used=20 >>>> then we won=E2=80=99t have this problem.) >>>>>=20 >>>>>> REFANY behaves the way the Green Book says it does. >>>>>=20 >>>>> You mean Systems Programming with Modula-3? >>>>>=20 >>>>> =E2=80=94 JC Chu >>>>>=20 >>>>> -----Original Message----- >>>>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>>>> Sent: Sunday, March 2, 2014 21:03 >>>>> To: JC Chu; rodney_bates at lcwb.coop >>>>> Cc: m3devel at elegosoft.com >>>>> Subject: Re: [M3devel] REFANY-keyed tables? >>>>>=20 >>>>>=20 >>>>> I just want to make an observation... >>>>>=20 >>>>> REFANY behaves the way the Green Book says it does. There's not a=20 >>>>> word in there about concurrent garbage collectors or bit-pattern=20 >>>>> representations of RE >>>> FANY. >>>>>=20 >>>>> If a, b : REFANY and a =3D b then a and b point to the same object. >>>>>=20 >>>>> You can't apply ^ to REFANY. The only thing you can do to a value = >beyond =3D is narrow it to another type. That's why there's no Hash for = >REFANY. >>>>> (Not because the garbage collector is implemented one way or=20 >>>>> another.) >>>>>=20 >>>>> Of course you can put REFANY in a list. You can make as many copies = >in as many places as you want and =3D will continue working. >>>>>=20 >>>>> The rest is implementation... >>>>>=20 >>>>> I'm not saying there isn't a lot of implementation, or that the=20 >>>>> implementation doesn't have to get clever about some things, but=20 >>>>> you really don't need to >>>> think about the implementation to know what you can and can't do = >with REFANY. It's all in the Green Book. >>>>>=20 >>>>> I definitely would not suggest messing with the garbage collector = >because you want to get something working with REFANY in a pure Modula-3 = >program. >>>>> It defeats the purpose of REFANY. >>>>>=20 >>>>> If you MUST hash a whole bunch of objects that have being REFANY as = > >>>>> their only thing in common I'd suggest using TYPECODE and=20 >>>>> registering hash procedures >>>> for each type you're interested in. This is a simple enough thing=20 >>>> that Modula-3's runtime "introspection" facilities more than=20 >>>> suffice. (Those facilitie s are more limited than Java's, for mostly = > >>>> good reasons.) >>>>>=20 >>>>> Mika >>>>> =20 From jcchu at acm.org Tue Mar 4 01:03:33 2014 From: jcchu at acm.org (JC Chu) Date: Tue, 4 Mar 2014 08:03:33 +0800 Subject: [M3devel] REFANY-keyed tables? In-Reply-To: <3E55E8A6-AF96-451D-9E94-3645DD4F050C@purdue.edu> References: <530EB0DC.6040809@lcwb.coop> <5310A82B.1040702@lcwb.coop> <20140302130243.7BD831A2095@async.async.caltech.edu> <53138D14.2030102@lcwb.coop> <20140302201741.C42E71A2094@async.async.caltech.edu> <3E55E8A6-AF96-451D-9E94-3645DD4F050C@purdue.edu> Message-ID: I see. So it is expected for garbage collectors to ensure that, as Tony put it, ?every reference to a particular evaluation of NEW always points to the same thing?. ? JC Chu -----Original Message----- From: Antony Hosking [mailto:hosking at purdue.edu] Sent: Monday, March 3, 2014 22:58 To: JC Chu Cc: mika at async.caltech.edu; Rodney M. Bates; ^M3DEVEL Subject: Re: [M3devel] REFANY-keyed tables? The GC maintains what is called a to-space invariant: all mutators are switched to the copy space before the collector starts moving objects. The read barrier ensures that mutators can never see old space objects. But as Mika notes, this is an implementation detail that ensures the language semantics in which reference equality just works as you would expect. The same is true of Java or any garbage collected language. Sent from my iPad On Mar 3, 2014, at 8:25 AM, JC Chu wrote: >> Another way of seeing it is that if st(x) = st(y) then x and y are pointing to the same object. > > > Well the language definition does state that st(x) = st(y) implies x = y (and the opposite implication is obvious). > > >>>> 5. But then y still has the old value: st(y) = s. > > >>> With a correctly implemented GC (which we have), step 5 can't happen. > > >> If x and y point to the same object and you don't assign to them, they keep pointing to the same object. > > > Hmm... I?ll glad this is the case, but I don?t see how it follows from the language definition alone. I mean the GC itself changes things on its own, without my having to assign to anything. If some poor GC did let step 5 happen and we have x # y and st(x) # st(y), it is still consistent with x = y iff st(x) = st(y). So this nice property is implementation-specific after all... Or did I miss anything from the language definition? > > ? JC Chu > > > ---------------------------------------- >> To: jcchu at acm.org >> CC: mika at async.caltech.edu; m3devel at elegosoft.com >> To: rodney_bates at lcwb.coop >> Subject: Re: [M3devel] REFANY-keyed tables? >> Date: Sun, 2 Mar 2014 12:17:41 -0800 >> From: mika at async.caltech.edu >> >> >> Right, right. >> >> Another way of seeing it is that if st(x) = st(y) then x and y are >> pointing to the same object. The language specification does talk >> about memory, albeit abstractly. >> >> If x and y point to the same object and you don't assign to them, >> they keep pointing to the same object. That is the language >> semantics, and yes, by The Green Book I mean Systems Programming with Modula-3. >> >> And yeah whatever the implementation does has to respect the language >> semantics. If the GC wants to change the bit representation of x then >> it has to change the bit representation of y in a way such that your >> program will always see x = y. Note that it is NOT literally required >> that the bit representation of x always equals the bit representation >> of y. But I do believe the GC accomplishes x = y by ensuring that >> their bit representations are always equal in any state where they >> may be checked by your program. >> >> Another way of looking at this is to consider references in the >> language as products of NEW. Every reference to a particular >> evaluation of NEW always points to the same thing. If NEW has only >> been evaluated once in your program, there can only be two REFANYs: >> NIL and the result of that NEW. Those are the language semantics. And >> of course the implementation has to go to some effort to ensure this >> property holds even as it fiddles with the bit representations of the >> two REFANYs. (NIL's bit representation is *probably* constant, but it >> doesn't have to be...) >> >> Mika >> >> "Rodney M. Bates" writes: >>> >>> >>> On 03/02/2014 09:00 AM, JC Chu wrote: >>>>> You can't apply ^ to REFANY. >>>> >>>> That was a mistake on my part. Let me rephrase my worry as follows, where st(r) denotes the storage location pointed to by the reference r. >>>> >>>> 1. x, y: REF T, where T has an equivalence relation T.Equal. >>>> 2. Initially, x = y # NIL and st(x) = st(y) = s. >>>> 3. Then the GC creates a copy s' of s. >>>> 4. Then the GC updates x so that st(x) = s'. >>>> 5. But then y still has the old value: st(y) = s. >>> >>> With a correctly implemented GC (which we have), step 5 can't >>> happen. The GC will prevent any use of y by a running mutator thread >>> until it (the GC) has updated y as well as x, so x = y again. My >>> questions to Tony were about how the >>> M3 GC accomplishes this, and it does. >>> >>> The motivatation for not giving REFANY a succeeding Hash is that, >>> after the updates, x = y # . >>> This would make a hash table fail, even if x = y works as defined. >>> Mika is right, as long as you stay in the safe subset of the >>> language. You simply can't write a hash function on a REFANY at all. >>> >>> Somebody could, however, declare the module with the Hash function >>> UNSAFE, LOOPHOLE the REFANY value to a Word.T (or something else, if >>> the sizes were not the same), and return that or something derived from it. >>> >>> It is never feasible in any language to define everything that can >>> happen, when type-unsafe techniques are used. That inevitably gets >>> into implementation details, which we often make assumptions about >>> rather cavalierly. Part of the wisdom of Modula-3 is that it clearly >>> defines what the safe subset is, then equally clearly defines the >>> semantics of that,, without getting into implementation. >>> >>> I was careless about glossing over the safe/unsafe distinction. >>> >>>> >>>> At step 5, we have x # y, st(x) # st(y), and T.Equal(x^, y^). If x >>>> is stored in a container for REFANY, then a membership check for x >>>> using y will fail, >>> because it can only be based on Refany.Equal. (If T.Equal is used >>> then we won?t have this problem.) >>>> >>>>> REFANY behaves the way the Green Book says it does. >>>> >>>> You mean Systems Programming with Modula-3? >>>> >>>> ? JC Chu >>>> >>>> -----Original Message----- >>>> From: mika at async.caltech.edu [mailto:mika at async.caltech.edu] >>>> Sent: Sunday, March 2, 2014 21:03 >>>> To: JC Chu; rodney_bates at lcwb.coop >>>> Cc: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] REFANY-keyed tables? >>>> >>>> >>>> I just want to make an observation... >>>> >>>> REFANY behaves the way the Green Book says it does. There's not a >>>> word in there about concurrent garbage collectors or bit-pattern >>>> representations of RE >>> FANY. >>>> >>>> If a, b : REFANY and a = b then a and b point to the same object. >>>> >>>> You can't apply ^ to REFANY. The only thing you can do to a value beyond = is narrow it to another type. That's why there's no Hash for REFANY. >>>> (Not because the garbage collector is implemented one way or >>>> another.) >>>> >>>> Of course you can put REFANY in a list. You can make as many copies in as many places as you want and = will continue working. >>>> >>>> The rest is implementation... >>>> >>>> I'm not saying there isn't a lot of implementation, or that the >>>> implementation doesn't have to get clever about some things, but >>>> you really don't need to >>> think about the implementation to know what you can and can't do with REFANY. It's all in the Green Book. >>>> >>>> I definitely would not suggest messing with the garbage collector because you want to get something working with REFANY in a pure Modula-3 program. >>>> It defeats the purpose of REFANY. >>>> >>>> If you MUST hash a whole bunch of objects that have being REFANY as >>>> their only thing in common I'd suggest using TYPECODE and >>>> registering hash procedures >>> for each type you're interested in. This is a simple enough thing >>> that Modula-3's runtime "introspection" facilities more than >>> suffice. (Those facilitie s are more limited than Java's, for mostly >>> good reasons.) >>>> >>>> Mika >>>> From hendrik at topoi.pooq.com Thu Mar 20 20:39:38 2014 From: hendrik at topoi.pooq.com (Hendrik Boom) Date: Thu, 20 Mar 2014 15:39:38 -0400 Subject: [M3devel] musl Message-ID: <20140320193938.GA18041@topoi.pooq.com> There's a new C library on the block. I don't know if this is at all relevant for Modula 3 implementation, but I thought i should mention it in case it is: http://www.musl-libc.org/ If nothing else, it has a different license. -- hendrik From jay.krell at cornell.edu Thu Mar 20 22:29:15 2014 From: jay.krell at cornell.edu (Jay K) Date: Thu, 20 Mar 2014 21:29:15 +0000 Subject: [M3devel] musl In-Reply-To: <20140320193938.GA18041@topoi.pooq.com> References: <20140320193938.GA18041@topoi.pooq.com> Message-ID: All of our use of the C library is from C/C++ now, not from Modula-3 directly. There is no longer C-library specific code/rewritten headers. Whatever your C compiler/flags use is what Modula-3 uses. - Jay > Date: Thu, 20 Mar 2014 15:39:38 -0400 > From: hendrik at topoi.pooq.com > To: m3devel at elegosoft.com > Subject: [M3devel] musl > > There's a new C library on the block. I don't know if this is at all > relevant for Modula 3 implementation, but I thought i should mention it > in case it is: > > http://www.musl-libc.org/ > > If nothing else, it has a different license. > > -- hendrik > -------------- next part -------------- An HTML attachment was scrubbed... URL: