[Newbies] Re: Adding methods to Integers...

Klaus D. Witzel klaus.witzel at cobss.com
Fri Apr 13 11:27:55 UTC 2007


Hi Bert,

on Thu, 12 Apr 2007 18:31:55 +0200, you wrote:

> This is actually wrong.

:)

> Only SmallIntegers are special [*].
>
> What happens is this: When you add two SmallIntegers (like "3 + 4"), and  
> the result is a SmallInteger, the result is calculated in the bytecode  
> directly. Otherwise, a regular send of #+ is performed.

Right.

> From there, everything else happens in the image,

Not really. (Integer>>#+ aNumber) sends (self digitAdd: aNumber) which is  
implemented as <primitive: 'primDigitAdd' module: 'LargeIntegers'> which  
is part of the VM. Of course the LargeIntegers module may be absent, have  
failed to load, may not like the argument, etc.

Only if (LargeIntegers>>#primDigitAdd: secondInteger) fails [whatever the  
reason, must not have anything to do with arithmetics] then "everything  
else" may happen in the image.

Back to the situation I had in mind (assuming MyPositiveInteger is a  
subclass of LargePositiveInteger):

| x y |
  x := LargePositiveInteger initializedInstance.
  y := (MyPositiveInteger basicNew: x basicSize)
   replaceFrom: 1 to: x basicSize with: x startingAt: 1.
(1 + y) class
  =>
LargePositiveInteger

But not: (y + 1) class
  =>
MyPositiveInteger

See, associativity at work ;-)

I have not checked whether the LargeIntegers module really does not like  
the argument (would seem plausible but it looks like it all relies on the  
#isInteger check in Integer>>#+, since from there on it "normally" is a  
SmallInteger or a #variableByteSubclass:).

> including conversion to LargeIntegers - see implementors of #+. Like, if  
> the receiver was a SmallInteger, it tries the "add" primitive, which  
> fails, and then the implementation of #+ in class Integer is invoked.  
> This method then creates a large integer.

It looks like in the (1 + y) case the LargeIntegers module creates the  
large integer. A simple test would be, to subclass ByteArray and have that  
respond true for #isInteger when used as argument in Integer>>#+ (but I  
haven't tried that).

> For the implementation of all this see #bytecodePrimAdd and  
> #primitiveAdd. You may have to load VMMaker first.

Sure, almost always have loaded that ;-)

/Klaus

> - Bert -
>
> [*] Well, Floats are optimized a bit, and we have a plugin to speed up  
> LargeIntegers, but this is all optional and  doesn't matter in this  
> discussion.
>
> On Apr 12, 2007, at 18:05 , Klaus D. Witzel wrote:
>
>> Hi Patrick,
>>
>> some of the symptoms you describe have to do with a small set of  
>> classes being "hardwired" in Squeak's virtual machine. To see which  
>> they are, evaluate (printIt)
>>
>>  Smalltalk specialObjectsArray select: [:each | each isBehavior]
>>
>> So when you do primitive arithmethic with your own subclass of  
>> LargePositiveInteger, the VM returns an instance of  
>> LargePositiveInteger (and not your subinstance of it).
>>
>> Of course the specialObjectsArray can be changed and from then on the  
>> VM (after being notified) will use your subclass but, I think this is  
>> not what you really want ;-)
>>
>> Putting your methods into Integer is fine as long as they do not  
>> conflict with anything else. Yes, this is the usual approach for adding  
>> new behavior to all the integers :)
>>
>> /Klaus
>>
>> On Thu, 12 Apr 2007 17:28:01 +0200, you wrote:
>>
>>>
>>> Background:
>>> ::::::::::::::::::::::
>>>
>>> 	The most recent MathFactor Podcast ( http://mathfactor.uark.edu/ )
>>> 	ended with a request to write a computer program that could, in
>>> 	principal, given enough time and memory, compute Graham's Number
>>> 	( http://mathworld.wolfram.com/GrahamsNumber.html ).
>>>
>>> 	Smalltalk was a natural choice since it already supports  
>>> LargeIntegers.
>>>
>>> Problem:
>>> :::::::::::::::
>>>
>>> 	Being new to Smalltalk, my first thought was that I should make my
>>> 	own class as a subclass of LargePositiveInteger, put my methods there,
>>> 	and violá.  Alas, no love.
>>>
>>> 	I ran into the following problems:
>>> 		* I couldn't find a way to give a value to myself.
>>> 		* I couldn't find a way to get integers to adapt to my class anyway.
>>>
>>> 	I ended up just adding my methods to the Integer class.  But, this  
>>> felt
>>> 	very naughty.  Is it the usual approach?
>>>
>>> Thanks,
>>> Patrick
>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners at lists.squeakfoundation.org
>> http://lists.squeakfoundation.org/mailman/listinfo/beginners




More information about the Beginners mailing list