SmallInteger someInstance == nil :(

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

SmallInteger someInstance == nil :(

marcel.taeumel
Hi all!

Why is "SmallInteger someInstance == nil"?

Best,
Marcel


Reply | Threaded
Open this post in threaded view
|

Re: SmallInteger someInstance == nil :(

fniephaus
On Tue, Jul 21, 2020 at 2:24 PM Marcel Taeumel <[hidden email]> wrote:
Hi all!

Why is "SmallInteger someInstance == nil"?

Because SmallIntegers are immediate and cannot be instantiated (`SmallInteger new` fails). This implies:

"SmallFloat64 someInstance == nil"
"Character someInstance == nil"

Why would you want someInstance of SmallInteger anyway?

Fabio
 

Best,
Marcel



Reply | Threaded
Open this post in threaded view
|

Re: SmallInteger someInstance == nil :(

marcel.taeumel
Hi Fabio.

From an object-oriented perspective, it would be nice to get "some instance" when asking a class in the system for #someInstance. :-)

As it is now, I have to start writing a little lookup table with "class == SmallInteger ifTrue: [ .... ]" to lookup exemplary instances for some classes in the system.

Best,
Marcel


Am 21.07.2020 14:53:31 schrieb Fabio Niephaus <[hidden email]>:

On Tue, Jul 21, 2020 at 2:24 PM Marcel Taeumel <[hidden email]> wrote:
Hi all!

Why is "SmallInteger someInstance == nil"?

Because SmallIntegers are immediate and cannot be instantiated (`SmallInteger new` fails). This implies:

"SmallFloat64 someInstance == nil"
"Character someInstance == nil"

Why would you want someInstance of SmallInteger anyway?

Fabio
 

Best,
Marcel



Reply | Threaded
Open this post in threaded view
|

Re: SmallInteger someInstance == nil :(

marcel.taeumel
Maybe I can check for #isImmediateClass first :-)

Am 21.07.2020 15:07:01 schrieb Marcel Taeumel <[hidden email]>:

Hi Fabio.

From an object-oriented perspective, it would be nice to get "some instance" when asking a class in the system for #someInstance. :-)

As it is now, I have to start writing a little lookup table with "class == SmallInteger ifTrue: [ .... ]" to lookup exemplary instances for some classes in the system.

Best,
Marcel


Am 21.07.2020 14:53:31 schrieb Fabio Niephaus <[hidden email]>:

On Tue, Jul 21, 2020 at 2:24 PM Marcel Taeumel <[hidden email]> wrote:
Hi all!

Why is "SmallInteger someInstance == nil"?

Because SmallIntegers are immediate and cannot be instantiated (`SmallInteger new` fails). This implies:

"SmallFloat64 someInstance == nil"
"Character someInstance == nil"

Why would you want someInstance of SmallInteger anyway?

Fabio
 

Best,
Marcel



Reply | Threaded
Open this post in threaded view
|

Re: SmallInteger someInstance == nil :(

fniephaus
On Tue, Jul 21, 2020 at 3:08 PM Marcel Taeumel <[hidden email]> wrote:
Maybe I can check for #isImmediateClass first :-)

That's a good idea. Note that primitiveSomeInstance also returns nil in case no instance exists (e.g. `EToyProjectDetailsMorph someInstance == nil`).
I believe the behavior you observe wrt immediates has historical reasons:
#someInstance returns the first instance found in the object memory, and you can use #nextInstance: for iteration (this mechanism was later replaced by #allInstances). Iterating instances doesn't make sense for immediates, the "same instance" can occur multiple times in the heap.

Fabio

Am 21.07.2020 15:07:01 schrieb Marcel Taeumel <[hidden email]>:

Hi Fabio.

From an object-oriented perspective, it would be nice to get "some instance" when asking a class in the system for #someInstance. :-)

As it is now, I have to start writing a little lookup table with "class == SmallInteger ifTrue: [ .... ]" to lookup exemplary instances for some classes in the system.

Best,
Marcel


Am 21.07.2020 14:53:31 schrieb Fabio Niephaus <[hidden email]>:

On Tue, Jul 21, 2020 at 2:24 PM Marcel Taeumel <[hidden email]> wrote:
Hi all!

Why is "SmallInteger someInstance == nil"?

Because SmallIntegers are immediate and cannot be instantiated (`SmallInteger new` fails). This implies:

"SmallFloat64 someInstance == nil"
"Character someInstance == nil"

Why would you want someInstance of SmallInteger anyway?

Fabio
 

Best,
Marcel




Reply | Threaded
Open this post in threaded view
|

Re: SmallInteger someInstance == nil :(

Eliot Miranda-2
In reply to this post by marcel.taeumel
Hi Marcel, Hi Fabio,

On Jul 21, 2020, at 5:24 AM, Marcel Taeumel <[hidden email]> wrote:


Hi all!

Why is "SmallInteger someInstance == nil"?

Fabio has it right.  Let me expand a little.

Historically the blue book Smalltalk-80 and Squeak have had garbage collectors that preserved allocation order, so that all instances could reliably be obtained by

    aClass firstInstance => first instance or nil
    anInstance nextInstance => next instance or nil

and all objects could reliably be obtained by

    Object someObject => anObject
    anObject nextObject => next object or nil

When Berkeley Smalltalk introduced generation scavenging allocation order was no longer preserved and so an allInstances primitive was introduced. So VisualWorks and the Spur implementation of Squeak and several other Smalltalks depend on allInstances and allObjects primitives.

In VisualWorks we sped up finding instances of a few classes by providing allInstancesOfAny: which takes an array of classes and has better performance because it makes one pass through the heap while the array of classes stays in the processor’s cache.

Like Marcel I thought that Character allInstances SmallInteger allInstances made sense as intervals, and implemented in VisualWorks so that SmallInteger allInstances answered (SmallInteger minVal to: SmallInteger maxVal).  But the cure was worse than the disease.  Tools that determined the memory usage of classes would have to special case the immediate classes because enumerating their instances, though now possible, took a looooong time ;-).  And of course extending the idea so that allObjects includes these is impossible; there’s not enough address space.  And so I would counsel against implementing allInstances for Character SmallFloat64 and SmallInteger.  It sounds great in theory but in practice it’s a pain in the ass.

Maybe someInstance should fail for immediate classes.  But more realistically we should deprecate someInstance, nextInstance, someObject and  nextObject, with helpful but succinct error messages.

Finally, Spur optimises allInstances.  A class’s identity hash is its instances’ class index.  So a class that doesn’t have an identity hash has no instances.  But if eg one creates a set of all classes they all get an identity hash and the optimization is defeated.  We could add a step in the release process to collect all classes with an identity hash but no instances, check if they’re in any hashed collections and void their identity hash if not.  There is a hidden primitive to test and to force setting of identity hashes fir nefarious purposes such as this.  But the primitive is not for every day use so it should remain hidden IMO.

Best,
Marcel


Reply | Threaded
Open this post in threaded view
|

Re: SmallInteger someInstance == nil :(

Florin Mateoc-4
In reply to this post by fniephaus
Actually, primitiveSomeInstance fails, it does not return nil. It is the image-side primitive failure code that returns nil.
Which brings us to the question: why not fix it in Smalltalk, if you think the behavior (as implemented in Behavior :)) is not appropriate for immediate classes?
If you override the method in the immediate classes and replace the primitive failure code with something more appropriate for each immediate class, you can have them return good exemplars

Florin

On Tue, Jul 21, 2020 at 9:21 AM Fabio Niephaus <[hidden email]> wrote:
On Tue, Jul 21, 2020 at 3:08 PM Marcel Taeumel <[hidden email]> wrote:
Maybe I can check for #isImmediateClass first :-)

That's a good idea. Note that primitiveSomeInstance also returns nil in case no instance exists (e.g. `EToyProjectDetailsMorph someInstance == nil`).
I believe the behavior you observe wrt immediates has historical reasons:
#someInstance returns the first instance found in the object memory, and you can use #nextInstance: for iteration (this mechanism was later replaced by #allInstances). Iterating instances doesn't make sense for immediates, the "same instance" can occur multiple times in the heap.

Fabio

Am 21.07.2020 15:07:01 schrieb Marcel Taeumel <[hidden email]>:

Hi Fabio.

From an object-oriented perspective, it would be nice to get "some instance" when asking a class in the system for #someInstance. :-)

As it is now, I have to start writing a little lookup table with "class == SmallInteger ifTrue: [ .... ]" to lookup exemplary instances for some classes in the system.

Best,
Marcel


Am 21.07.2020 14:53:31 schrieb Fabio Niephaus <[hidden email]>:

On Tue, Jul 21, 2020 at 2:24 PM Marcel Taeumel <[hidden email]> wrote:
Hi all!

Why is "SmallInteger someInstance == nil"?

Because SmallIntegers are immediate and cannot be instantiated (`SmallInteger new` fails). This implies:

"SmallFloat64 someInstance == nil"
"Character someInstance == nil"

Why would you want someInstance of SmallInteger anyway?

Fabio
 

Best,
Marcel





Reply | Threaded
Open this post in threaded view
|

Re: SmallInteger someInstance == nil :(

Florin Mateoc-4
First off, apologies for top-posting, fixed below, with some additional comments.

On Tue, Jul 21, 2020 at 11:56 AM Florin Mateoc <[hidden email]> wrote:
On Tue, Jul 21, 2020 at 9:21 AM Fabio Niephaus <[hidden email]> wrote:
On Tue, Jul 21, 2020 at 3:08 PM Marcel Taeumel <[hidden email]> wrote:
Maybe I can check for #isImmediateClass first :-)

That's a good idea. Note that primitiveSomeInstance also returns nil in case no instance exists (e.g. `EToyProjectDetailsMorph someInstance == nil`).
I believe the behavior you observe wrt immediates has historical reasons:
#someInstance returns the first instance found in the object memory, and you can use #nextInstance: for iteration (this mechanism was later replaced by #allInstances). Iterating instances doesn't make sense for immediates, the "same instance" can occur multiple times in the heap.

Fabio


Actually, primitiveSomeInstance fails, it does not return nil. It is the image-side primitive failure code that returns nil.
Which brings us to the question: why not fix it in Smalltalk, if you think the behavior (as implemented in Behavior :)) is not appropriate for immediate classes?
If you override the method in the immediate classes and replace the primitive failure code with something more appropriate for each immediate class, you can have them return good exemplars

Also note that, as Eliot said, nextInstance does not make sense for immediate classes. This implies that someInstance does not make sense either when thought of as the dual of nextInstace (which it is, in many scenarios).
But I think someInstance can make sense on its own, as in your scenario, that is the context in which I proposed to "fix it"

Florin
 

Am 21.07.2020 15:07:01 schrieb Marcel Taeumel <[hidden email]>:

Hi Fabio.

From an object-oriented perspective, it would be nice to get "some instance" when asking a class in the system for #someInstance. :-)

As it is now, I have to start writing a little lookup table with "class == SmallInteger ifTrue: [ .... ]" to lookup exemplary instances for some classes in the system.

Best,
Marcel


Am 21.07.2020 14:53:31 schrieb Fabio Niephaus <[hidden email]>:

On Tue, Jul 21, 2020 at 2:24 PM Marcel Taeumel <[hidden email]> wrote:
Hi all!

Why is "SmallInteger someInstance == nil"?

Because SmallIntegers are immediate and cannot be instantiated (`SmallInteger new` fails). This implies:

"SmallFloat64 someInstance == nil"
"Character someInstance == nil"

Why would you want someInstance of SmallInteger anyway?

Fabio
 

Best,
Marcel