New primitive, if any one feels like writing it

82 views
Skip to first unread message

Louis LaBrunda

unread,
Nov 25, 2011, 10:31:45 AM11/25/11
to va-sma...@googlegroups.com
Hi Group,

A little while I was thinking about how data got compared back when I worked on IBM mainframes (don't ask why my brain works in such a way that I should think about that).  Anyway, those computers and I guess most computers today, do the comparison and set a flag (I think two bits) that indicates if the first item was less than, equal to or greater than the second.  Branches can then be executed based upon the flag.  In VA Smalltalk we would have to do the compare twice to get the same three conditions.  For number, this is probably not too big a deal but for long strings it could matter.

I was thinking that it might be nice if Smalltalk virtual machines could mimic this kind of comparison in a way that didn't require doing the compare twice.  I don't really have a need for this but someone might so I thought I would throw the idea out there.  I took a look at VA Smalltalk and didn't find anything.  I then took a look at Squeak and found a few methods that ultimately call a primitive to do the compare.  The returned result is an integer 1, 2 or 3 indicating the less than, equal to or greater than condition.

The Squeak methods are:

compare: aString
compare: aString caseSensitive: aBool
compare: string1 with: string2 collated: order

where the first two, call the last one (with parameters set) and the last one calls the primitive.  The primitive seems very general in that it has a collating order of characters parameter.  I don't know if there would be much need for a collating order of characters parameter in VA Smalltalk.  A case sensitive or insensitive option might be nice.

I do think that executing a block might be a better way to go than returning a number.  Something like:

compare: aString ifLow: lowBlock ifEqual: equalBlock ifHigh: highBlock

This is more concise than having to do the compare and then test the number result to execute some code.  One could alway put 1, 2 and 3 in the respective blocks to get the same results as Squeak if that was needed.

No one should feel any pressure to implement this on my account but maybe someone out there could use it to clean/speed up their code.

Lou


Marten Feldtmann

unread,
Nov 25, 2011, 11:36:46 AM11/25/11
to va-sma...@googlegroups.com
You may have a look at:

LCCollate>>compareString: string1 and: string2

that should give you the base you are looking for ....

Marten

Louis LaBrunda

unread,
Nov 28, 2011, 9:45:06 AM11/28/11
to va-sma...@googlegroups.com
Hi Marten,

Thanks for the info.  I wondered why there wasn't a VA Smalltalk equivalent.  Didn't think to look at LCCollate.

I still think that executing a block would be better than answering an int but as I said I am not really in need of the feature, I was just thinking about it.

Lou

Louis LaBrunda

unread,
Nov 30, 2011, 10:09:05 AM11/30/11
to va-sma...@googlegroups.com
Hi All,

After thinking about this some more, I remembered that one reason for a primitive to compare strings and not need to compare them twice is to save time.  Given this, a simple primitive that just does a case insensitive compare and executes a block would be valuable.

Lou

Marten Feldtmann

unread,
Nov 30, 2011, 5:44:33 PM11/30/11
to va-sma...@googlegroups.com
Louis,

String>>compareWith: anotherString ifLess: lessBlock equal: equalBlock more: moreBlock
    "
        'b' compareWith: 'b' ifLess: [ :a :b | 'Less' ] equal: [ :a :b | 'Equal'] more: [ :a :b | 'More']
    "

    | rc |
   
    rc := Locale current lcCollate compareString: self and: anotherString.   
    rc = 2 ifTrue:[ ^lessBlock value: self value: anotherString ].
    rc = 1 ifTrue:[ ^equalBlock value: self value: anotherString ].
    rc = 3 ifTrue:[ ^moreBlock value: self value: anotherString ].
   
    ^nil

Louis LaBrunda

unread,
Nov 30, 2011, 6:46:42 PM11/30/11
to va-sma...@googlegroups.com
Hi Marten,

I'm not sure what your code above is trying to do but that aside, I am talking about a primitive that would be called for the following:

compare: aString ifLow: lowBlock ifEqual: equalBlock ifHigh: highBlock

the primitive would would do the compare in much the same way the current primitive does but without the locale overhead (just an ASCII) and execute the appropriate block.

Without that primitive, I could do this:

compare: aString ifLow: lowBlock ifEqual: equalBlock ifHigh: highBlock

Lou 


Louis LaBrunda

unread,
Nov 30, 2011, 6:52:17 PM11/30/11
to va-sma...@googlegroups.com
sorry, hit the wrong key and off the post went.

Without that primitive, I could do this:

compare: aString ifLow: lowBlock ifEqual: equalBlock ifHigh: highBlock
| rc |

rc := Locale current lcCollate compareString: self and: aString.
rc = 1 ifTrue:[^lowBlock value].
rc = 2 ifTrue:[^equalBlock value].
rc = 3 ifTrue:[^highBlock value].


Lou


Marten Feldtmann

unread,
Dec 1, 2011, 1:10:56 AM12/1/11
to va-sma...@googlegroups.com
I would guess, that the compare is the most expensive operation here (for longer strings) - the rest should be done in Smalltalk - simply because the format and specification of the specific blocks may vary according to the users needs .... as our both examples show.




Reply all
Reply to author
Forward
0 new messages