How to become immediate objects? :-)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

How to become immediate objects? :-)

marcel.taeumel
Hi, all!

I suppose that since ModificationForbidden and read-only objects, the following is no longer possible:

MyExternalResource allInstancesDo: [:resource |
   resource becomeForward: #notAvailable].

What to do now? Introduce a custom, mutable, placeholder object instead?

Best,
Marcel


Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Levente Uzonyi
Hi Marcel,

That's a bug. The argument of #becomeForward: is never attempted to be
modified. The following should work:

| a |
a := Object new.
a becomeForward: #foo.
self assert: a = 'foo'.

The error it raises is nonsense.


Levente

On Tue, 14 Apr 2020, Marcel Taeumel wrote:

> Hi, all!
>
> I suppose that since ModificationForbidden and read-only objects, the following is no longer possible:
>
> MyExternalResource allInstancesDo: [:resource |
>    resource becomeForward: #notAvailable].
>
> What to do now? Introduce a custom, mutable, placeholder object instead?
>
> Best,
> Marcel
>
>

Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Eliot Miranda-2


> On Apr 14, 2020, at 6:40 AM, Levente Uzonyi <[hidden email]> wrote:
>
> Hi Marcel,
>
> That's a bug. The argument of #becomeForward: is never attempted to be modified. The following should work:
>
> | a |
> a := Object new.
> a becomeForward: #foo.
> self assert: a = 'foo'.
>
> The error it raises is nonsense.

+1

>
>
> Levente
>
>> On Tue, 14 Apr 2020, Marcel Taeumel wrote:
>>
>> Hi, all!
>> I suppose that since ModificationForbidden and read-only objects, the following is no longer possible:
>> MyExternalResource allInstancesDo: [:resource |
>>    resource becomeForward: #notAvailable].
>> What to do now? Introduce a custom, mutable, placeholder object instead?
>> Best,
>> Marcel
>

Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Levente Uzonyi
Hi Eliot,

On Tue, 14 Apr 2020, Eliot Miranda wrote:

>
>
>> On Apr 14, 2020, at 6:40 AM, Levente Uzonyi <[hidden email]> wrote:
>>
>> Hi Marcel,
>>
>> That's a bug. The argument of #becomeForward: is never attempted to be modified. The following should work:
>>
>> | a |
>> a := Object new.
>> a becomeForward: #foo.
>> self assert: a = 'foo'.
>>
>> The error it raises is nonsense.
>
> +1
Well, the thing is that #becomeForward: tries to copy the identityHash too
hence the error. I'm not sure whether PrimErrInapropriate is the right
choice but that's what the code produces and it matches what the comment
of SpurMemoryManager >> #containsOnlyValidBecomeObjects:and:twoWay:copyHash:
states. IMHO PrimErrNoModification would be more appropriate in this case.

So, the presence of the error is expected. The correct code is:

| a |
a := Object new.
a becomeForward: #foo copyHash: false.
self assert: a = #foo.

Which works as expected.


Levente

>
>>
>>
>> Levente
>>
>>> On Tue, 14 Apr 2020, Marcel Taeumel wrote:
>>>
>>> Hi, all!
>>> I suppose that since ModificationForbidden and read-only objects, the following is no longer possible:
>>> MyExternalResource allInstancesDo: [:resource |
>>>    resource becomeForward: #notAvailable].
>>> What to do now? Introduce a custom, mutable, placeholder object instead?
>>> Best,
>>> Marcel
>>

Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Eliot Miranda-2
Hi Levente,

On Tue, Apr 14, 2020 at 12:52 PM Levente Uzonyi <[hidden email]> wrote:
Hi Eliot,

On Tue, 14 Apr 2020, Eliot Miranda wrote:

>
>
>> On Apr 14, 2020, at 6:40 AM, Levente Uzonyi <[hidden email]> wrote:
>>
>> Hi Marcel,
>>
>> That's a bug. The argument of #becomeForward: is never attempted to be modified. The following should work:
>>
>> | a |
>> a := Object new.
>> a becomeForward: #foo.
>> self assert: a = 'foo'.
>>
>> The error it raises is nonsense.
>
> +1

Well, the thing is that #becomeForward: tries to copy the identityHash too
hence the error. I'm not sure whether PrimErrInapropriate is the right
choice but that's what the code produces and it matches what the comment
of SpurMemoryManager >> #containsOnlyValidBecomeObjects:and:twoWay:copyHash:
states. IMHO PrimErrNoModification would be more appropriate in this case.

So, the presence of the error is expected. The correct code is:

| a |
a := Object new.
a becomeForward: #foo copyHash: false.
self assert: a = #foo.

Which works as expected.

Right.  A couple of questions are
1. what the f**k are become: becomeForward: becomeForward:copyHash: et al doing in ProtoObject?  (IMO, they should be in Object and have no business being in ProtoObject whatsoever).
2. whether becomeForward: should do copyHash: true by default.  This seems wrong to me, and implementing is as copyHash: false makes more sense.  But I'm wondering if there are important use cases.  Vanessa, any recollections on this?

But the VM bug is here in SpurMemoryManager>>containsOnlyValidBecomeObjects:and:twoWay:copyHash:

    (copyHash and: [(self isImmediate: oop2) or: [self isImmutable: oop2]]) ifTrue:
[^PrimErrInappropriate].

it should read something like
    copyHash ifTrue:
[(self isImmediate: oop2) ifTrue:
[^PrimErrInappropriate].
(self isImmutable: oop2) ifTrue:
[^PrimErrNoModification]].

I'll make it so.

Levente

>
>>
>>
>> Levente
>>
>>> On Tue, 14 Apr 2020, Marcel Taeumel wrote:
>>>
>>> Hi, all!
>>> I suppose that since ModificationForbidden and read-only objects, the following is no longer possible:
>>> MyExternalResource allInstancesDo: [:resource |
>>>    resource becomeForward: #notAvailable].
>>> What to do now? Introduce a custom, mutable, placeholder object instead?
>>> Best,
>>> Marcel
>>


--
_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Chris Muller-3
Hi Eliot,
 
Right.  A couple of questions are
1. what the f**k are become: becomeForward: becomeForward:copyHash: et al doing in ProtoObject?  (IMO, they should be in Object and have no business being in ProtoObject whatsoever).

For Proxy's.  They don't typically inherit from Object, but must be able to become their normal object upon receiving a message it #doesNotUnderstand:.  Maybe you're implying those programs should be using the mirror primitives, but those weren't always available, so hopefully that at least answers your question.

2. whether becomeForward: should do copyHash: true by default.  This seems wrong to me, and implementing is as copyHash: false makes more sense.  But I'm wondering if there are important use cases.

Yes, changing the identityHash without changing the identity is basically "wrong", and even dangerous if it's a system Symbol used as keys in IdentityDictionary's like Environments, etc.

   Object new becomeForward: #size   "do it = lock up your image"

 - Chris


Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

codefrau
In reply to this post by Eliot Miranda-2
On Tue, Apr 14, 2020 at 1:44 PM Eliot Miranda <[hidden email]> wrote:

2. whether becomeForward: should do copyHash: true by default.  This seems wrong to me, and implementing is as copyHash: false makes more sense.  But I'm wondering if there are important use cases.  Vanessa, any recollections on this?

I think last time 'round we agreed that the default should not copy the hash, but were somewhat afraid to break things if we changed the default. Now, at the beginning of a new release cycle, would be a good time.

- Vanessa - 
 


Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Levente Uzonyi
In reply to this post by Chris Muller-3
Hi Chris,

On Tue, 14 Apr 2020, Chris Muller wrote:

> Hi Eliot,
>  
>
>       Right.  A couple of questions are
> 1. what the f**k are become: becomeForward: becomeForward:copyHash: et al doing in ProtoObject?  (IMO, they should be in Object and have no business being in ProtoObject whatsoever).
>
>
> For Proxy's.  They don't typically inherit from Object, but must be able to become their normal object upon receiving a message it #doesNotUnderstand:.  Maybe you're implying those programs should be using the mirror
> primitives, but those weren't always available, so hopefully that at least answers your question.

The primitives are defined on arrays. A proxy can and should always do

  { self } elementsForwardIdentityTo: { proxiedObject }

So, that's not a reason to have those methods implemented by ProtoObject.

>
>       2. whether becomeForward: should do copyHash: true by default.  This seems wrong to me, and implementing is as copyHash: false makes more sense.  But I'm wondering if there are important use cases.
>
>
> Yes, changing the identityHash without changing the identity is basically "wrong", and even dangerous if it's a system Symbol used as keys in IdentityDictionary's like Environments, etc.
>
>    Object new becomeForward: #size   "do it = lock up your image"

The VM won't let you overwrite the Symbol's identityHash in current
Trunk, you'll get an error instead.


Levente

>
>  - Chris
>
>

Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

marcel.taeumel
Hi all!

Thank you all for the clarification. Yes, please let's not copy the identity hash by default.

+1 on changing the default behind #becomeForward:

Best,
Marcel

Am 15.04.2020 09:59:09 schrieb Levente Uzonyi <[hidden email]>:

Hi Chris,

On Tue, 14 Apr 2020, Chris Muller wrote:

> Hi Eliot,
>  
>
> Right.  A couple of questions are
> 1. what the f**k are become: becomeForward: becomeForward:copyHash: et al doing in ProtoObject?  (IMO, they should be in Object and have no business being in ProtoObject whatsoever).
>
>
> For Proxy's.  They don't typically inherit from Object, but must be able to become their normal object upon receiving a message it #doesNotUnderstand:.  Maybe you're implying those programs should be using the mirror
> primitives, but those weren't always available, so hopefully that at least answers your question.

The primitives are defined on arrays. A proxy can and should always do

{ self } elementsForwardIdentityTo: { proxiedObject }

So, that's not a reason to have those methods implemented by ProtoObject.

>
> 2. whether becomeForward: should do copyHash: true by default.  This seems wrong to me, and implementing is as copyHash: false makes more sense.  But I'm wondering if there are important use cases.
>
>
> Yes, changing the identityHash without changing the identity is basically "wrong", and even dangerous if it's a system Symbol used as keys in IdentityDictionary's like Environments, etc.
>
>    Object new becomeForward: #size   "do it = lock up your image"

The VM won't let you overwrite the Symbol's identityHash in current
Trunk, you'll get an error instead.


Levente

>
>  - Chris
>
>


Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Jakob Reschke
Hi,

The reason I read somewhere for the copyHash true default is that one would have to rehash collections that contain the involved objects if the hash did change.

Anything to be done in this regard of you change the default?

Kind regards,
Jakob 

Marcel Taeumel <[hidden email]> schrieb am Mi., 15. Apr. 2020, 11:56:
Hi all!

Thank you all for the clarification. Yes, please let's not copy the identity hash by default.

+1 on changing the default behind #becomeForward:

Best,
Marcel

Am 15.04.2020 09:59:09 schrieb Levente Uzonyi <[hidden email]>:

Hi Chris,

On Tue, 14 Apr 2020, Chris Muller wrote:

> Hi Eliot,
>  
>
> Right.  A couple of questions are
> 1. what the f**k are become: becomeForward: becomeForward:copyHash: et al doing in ProtoObject?  (IMO, they should be in Object and have no business being in ProtoObject whatsoever).
>
>
> For Proxy's.  They don't typically inherit from Object, but must be able to become their normal object upon receiving a message it #doesNotUnderstand:.  Maybe you're implying those programs should be using the mirror
> primitives, but those weren't always available, so hopefully that at least answers your question.

The primitives are defined on arrays. A proxy can and should always do

{ self } elementsForwardIdentityTo: { proxiedObject }

So, that's not a reason to have those methods implemented by ProtoObject.

>
> 2. whether becomeForward: should do copyHash: true by default.  This seems wrong to me, and implementing is as copyHash: false makes more sense.  But I'm wondering if there are important use cases.
>
>
> Yes, changing the identityHash without changing the identity is basically "wrong", and even dangerous if it's a system Symbol used as keys in IdentityDictionary's like Environments, etc.
>
>    Object new becomeForward: #size   "do it = lock up your image"

The VM won't let you overwrite the Symbol's identityHash in current
Trunk, you'll get an error instead.


Levente

>
>  - Chris
>
>



Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

marcel.taeumel
Hi Jakob,

collections use #hash, which can be different for different objects. So rehashing is important after #becomeForward: in any case.

Best,
Marcel

Am 15.04.2020 13:18:59 schrieb Jakob Reschke <[hidden email]>:

Hi,

The reason I read somewhere for the copyHash true default is that one would have to rehash collections that contain the involved objects if the hash did change.

Anything to be done in this regard of you change the default?

Kind regards,
Jakob 

Marcel Taeumel <[hidden email]> schrieb am Mi., 15. Apr. 2020, 11:56:
Hi all!

Thank you all for the clarification. Yes, please let's not copy the identity hash by default.

+1 on changing the default behind #becomeForward:

Best,
Marcel

Am 15.04.2020 09:59:09 schrieb Levente Uzonyi <[hidden email]>:

Hi Chris,

On Tue, 14 Apr 2020, Chris Muller wrote:

> Hi Eliot,
>  
>
> Right.  A couple of questions are
> 1. what the f**k are become: becomeForward: becomeForward:copyHash: et al doing in ProtoObject?  (IMO, they should be in Object and have no business being in ProtoObject whatsoever).
>
>
> For Proxy's.  They don't typically inherit from Object, but must be able to become their normal object upon receiving a message it #doesNotUnderstand:.  Maybe you're implying those programs should be using the mirror
> primitives, but those weren't always available, so hopefully that at least answers your question.

The primitives are defined on arrays. A proxy can and should always do

{ self } elementsForwardIdentityTo: { proxiedObject }

So, that's not a reason to have those methods implemented by ProtoObject.

>
> 2. whether becomeForward: should do copyHash: true by default.  This seems wrong to me, and implementing is as copyHash: false makes more sense.  But I'm wondering if there are important use cases.
>
>
> Yes, changing the identityHash without changing the identity is basically "wrong", and even dangerous if it's a system Symbol used as keys in IdentityDictionary's like Environments, etc.
>
>    Object new becomeForward: #size   "do it = lock up your image"

The VM won't let you overwrite the Symbol's identityHash in current
Trunk, you'll get an error instead.


Levente

>
>  - Chris
>
>



Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Levente Uzonyi
In reply to this post by Jakob Reschke
Hi Jakob,

On Wed, 15 Apr 2020, Jakob Reschke wrote:

> Hi,
> The reason I read somewhere for the copyHash true default is that one would have to rehash collections that contain the involved objects if the hash did change.
>
> Anything to be done in this regard of you change the default?

That is correct. If the identity hash is not copied over, then you have
to rehash any hashed collection which
- holds the receiver of #becomeForward: (before the identity is
forwarded), or the receiver or the argument of #become:
- derives the hash value from the objects' identity hash.

But the hash can't always be copied over, so it's a tough decision what
the default should be:
- if the hash is not copied by default, the lack of rehashing will cause
elements to be not found in the affected collections
- if the hash is copied, runtime errors will be raised when coping the
hash is not possible.

Perhaps the best would be if before saving a method sending #become: or
#becomeForward:, the code editor warned the user about the possible future
consequences and suggested them to switch over to the #copyHash:
variants.
There could also be lint rules covering these cases.


Levente

>
> Kind regards,
> Jakob 
>
> Marcel Taeumel <[hidden email]> schrieb am Mi., 15. Apr. 2020, 11:56:
>       Hi all!
> Thank you all for the clarification. Yes, please let's not copy the identity hash by default.
>
> +1 on changing the default behind #becomeForward:
>
> Best,
> Marcel
>
>       Am 15.04.2020 09:59:09 schrieb Levente Uzonyi <[hidden email]>:
>
>       Hi Chris,
>
>       On Tue, 14 Apr 2020, Chris Muller wrote:
>
>       > Hi Eliot,
>       >  
>       >
>       > Right.  A couple of questions are
>       > 1. what the f**k are become: becomeForward: becomeForward:copyHash: et al doing in ProtoObject?  (IMO, they should be in Object and have no business being in ProtoObject whatsoever).
>       >
>       >
>       > For Proxy's.  They don't typically inherit from Object, but must be able to become their normal object upon receiving a message it #doesNotUnderstand:.  Maybe you're implying those programs should be using
>       the mirror
>       > primitives, but those weren't always available, so hopefully that at least answers your question.
>
>       The primitives are defined on arrays. A proxy can and should always do
>
>       { self } elementsForwardIdentityTo: { proxiedObject }
>
>       So, that's not a reason to have those methods implemented by ProtoObject.
>
>       >
>       > 2. whether becomeForward: should do copyHash: true by default.  This seems wrong to me, and implementing is as copyHash: false makes more sense.  But I'm wondering if there are important use cases.
>       >
>       >
>       > Yes, changing the identityHash without changing the identity is basically "wrong", and even dangerous if it's a system Symbol used as keys in IdentityDictionary's like Environments, etc.
>       >
>       >    Object new becomeForward: #size   "do it = lock up your image"
>
>       The VM won't let you overwrite the Symbol's identityHash in current
>       Trunk, you'll get an error instead.
>
>
>       Levente
>
>       >
>       >  - Chris
>       >
>       >
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Chris Muller-3
But the hash can't always be copied over, so it's a tough decision what
the default should be:
- if the hash is not copied by default, the lack of rehashing will cause
elements to be not found in the affected collections 
- if the hash is copied, runtime errors will be raised when coping the
hash is not possible.

I think a "lack of rehashing" issue could also occur in the latter case, too, if the target of the become (the argument) was in a identity hashed collection..



Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Eliot Miranda-2
Hi Chris, Hi All,

On Wed, Apr 15, 2020 at 3:14 PM Chris Muller <[hidden email]> wrote:
But the hash can't always be copied over, so it's a tough decision what
the default should be:
- if the hash is not copied by default, the lack of rehashing will cause
elements to be not found in the affected collections 
- if the hash is copied, runtime errors will be raised when coping the
hash is not possible.

I think a "lack of rehashing" issue could also occur in the latter case, too, if the target of the become (the argument) was in a identity hashed collection..

Right.  The major use case for which copyHash being true is correct is class reshaping where new instances of the reshaped class are created and all existing instances are forwarded to the new instances.  Were the new instances' hashes too be left alone, all hell would break lose.

So I did the deed.  See commits below.  elementsForwardIdentityTo: now uses the primitive (number) that implicitly has copyHash false. elementsForwardIdentityAndHashTo: has the old behaviour with copyHash true; it is effectively the rename ing of the old elementsForwardIdentityTo:.  The become: wrappers have been moved down to Object from ProtoObject.  The ClassBuilder and ClassDescription have been changed to use elementsForwardIdentityAndHashTo: when migrating.  So hopefully the system should continue as normal except that a casual use of becomeForward: to a read-only object should now work as expected.

The change to the error c ode of the primitive will require new VMs.  Those should be ready by week's end. Apologies until then.

Name: Collections-eem.885

Author: eem

Time: 15 April 2020, 4:37:54.800631 pm

UUID: 45d219d3-6ed0-4401-a820-44eebe21d71a

Ancestors: Collections-eem.883, Collections-dtl.884


Switch elementsForwardIdentityTo: to not copy the hash, see http://forum.world.st/How-to-become-immediate-objects-td5114931.html.

Add elementsForwardIdentityAndHashTo: for the old behavior.


Name: Kernel-eem.1322

Author: eem

Time: 15 April 2020, 4:39:29.367332 pm

UUID: 94e874d1-0572-4a1d-9934-edcf87b8ecb5

Ancestors: Kernel-eem.1321


Move the become: methods from ProtoObject to Object.  See http://forum.world.st/How-to-become-immediate-objects-td5114931.html


Name: Kernel-eem.1323

Author: eem

Time: 15 April 2020, 4:46:14.261016 pm

UUID: 5ea740f0-f4c6-4808-b7b6-2e3aee87aa91

Ancestors: Kernel-eem.1322


Update the ClassBuilder and instance migration, given the changes in Collections-eem.885.  See http://forum.world.st/How-to-become-immediate-objects-td5114931.html.


 


--
_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Levente Uzonyi
In reply to this post by Chris Muller-3
On Wed, 15 Apr 2020, Chris Muller wrote:

>       But the hash can't always be copied over, so it's a tough decision what
>       the default should be:
>       - if the hash is not copied by default, the lack of rehashing will cause
>       elements to be not found in the affected collections 
>
>       - if the hash is copied, runtime errors will be raised when coping the
>       hash is not possible.
>
>
> I think a "lack of rehashing" issue could also occur in the latter case, too, if the target of the become (the argument) was in a identity hashed collection..
Right. #become: doesn't change the identity hashes.


Levente

>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: How to become immediate objects? :-)

Chris Muller-3
In reply to this post by Eliot Miranda-2

On Wed, Apr 15, 2020 at 7:02 PM Eliot Miranda <[hidden email]> wrote:
Hi Chris, Hi All,

On Wed, Apr 15, 2020 at 3:14 PM Chris Muller <[hidden email]> wrote:
But the hash can't always be copied over, so it's a tough decision what
the default should be:
- if the hash is not copied by default, the lack of rehashing will cause
elements to be not found in the affected collections 
- if the hash is copied, runtime errors will be raised when coping the
hash is not possible.

I think a "lack of rehashing" issue could also occur in the latter case, too, if the target of the become (the argument) was in a identity hashed collection..

Right.  The major use case for which copyHash being true is correct is class reshaping where new instances of the reshaped class are created and all existing instances are forwarded to the new instances.  Were the new instances' hashes too be left alone, all hell would break lose.

So I did the deed.  See commits below.  elementsForwardIdentityTo: now uses the primitive (number) that implicitly has copyHash false. elementsForwardIdentityAndHashTo: has the old behaviour with copyHash true; it is effectively the rename ing of the old elementsForwardIdentityTo:.  The become: wrappers have been moved down to Object from ProtoObject.  The ClassBuilder and ClassDescription have been changed to use elementsForwardIdentityAndHashTo: when migrating.  So hopefully the system should continue as normal except that a casual use of becomeForward: to a read-only object should now work as expected.

The change to the error c ode of the primitive will require new VMs.  Those should be ready by week's end. Apologies until then.

Name: Collections-eem.885

Author: eem

Time: 15 April 2020, 4:37:54.800631 pm

UUID: 45d219d3-6ed0-4401-a820-44eebe21d71a

Ancestors: Collections-eem.883, Collections-dtl.884


Switch elementsForwardIdentityTo: to not copy the hash, see http://forum.world.st/How-to-become-immediate-objects-td5114931.html.

Add elementsForwardIdentityAndHashTo: for the old behavior.


Name: Kernel-eem.1322

Author: eem

Time: 15 April 2020, 4:39:29.367332 pm

UUID: 94e874d1-0572-4a1d-9934-edcf87b8ecb5

Ancestors: Kernel-eem.1321


Move the become: methods from ProtoObject to Object.  See http://forum.world.st/How-to-become-immediate-objects-td5114931.html


Name: Kernel-eem.1323

Author: eem

Time: 15 April 2020, 4:46:14.261016 pm

UUID: 5ea740f0-f4c6-4808-b7b6-2e3aee87aa91

Ancestors: Kernel-eem.1322


Update the ClassBuilder and instance migration, given the changes in Collections-eem.885.  See http://forum.world.st/How-to-become-immediate-objects-td5114931.html.


 


--
_,,,^..^,,,_
best, Eliot