Hi all! Why is "SmallInteger someInstance == nil"? Best, Marcel |
On Tue, Jul 21, 2020 at 2:24 PM Marcel Taeumel <[hidden email]> wrote:
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
|
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
|
Maybe I can check for #isImmediateClass first :-)
|
On Tue, Jul 21, 2020 at 3:08 PM Marcel Taeumel <[hidden email]> wrote:
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
|
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:
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.
|
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:
|
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:
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
|
Free forum by Nabble | Edit this page |