[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