[futurebasic] Fun for thought

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : September 1998 : Group Archive : Group : All Groups

From: jonathan <jonathan@...>
Date: Sam, 26 Sep 98 15:49:36 +0200
Food for thought
(Proviso: this is for lurkers, not for the usual posters
for whom this is old hat - but all reactions welcomed)

When beginning to program we tend:
1/ to be disorganised
2/ to use glabals for everything
3/ not to use LOCAL MODE on FN's as we don't see how.

So this is a discussion on an aspect of, what has come to
be known as 'bit-twiddling', to stimulate debate.

First off: why use LOCAL MODE on an FN? Reusability.
If you write your FNs as local, with documentation on input
and results, with all variables DIMmed, it is much easier
to just grab it, reuse it in a another project, or pass it
on to someone else.

An FN can give a result to say that it executed OK, or it can
test something, this leads to lines like this:

IF( FN myDoSomethingGreat( doItOnThis) <> _noErr) THEN FN doOops
or
IF( FN doesTheDogWantToGoWalkies ) THEN FN goWalkies

We are getting back either a boolean (yes/no, true/false)
or a range of values( 0= _noErr, 1 = _soAndSoError etc.)

But what happens when you need to return _more_than_one_ result?
At this point, you will probably either pass a record, and change
info in the passed record, or use a range of globals, which will
decrease portability of your code.
Passing a record can be great (albeit confusing at first, but
that's not the subject today); using a handful of globals, especially
if the only time they're used is to carry back the results is
bothersome, memory consuming and a bunch of other ms words.

So how to get round this? Lets examine our dumb FN

CLEAR LOCAL MODE
LOCAL FN doSomethingDumb( passedValue)
DIM result%
'  here something dumb is done
'  and the value, or values will have
'  to passed back.
...
END FN = result%

We tend to think of things around us as simple well defined
blobs (car, house, train) and we carry this into programming.
What is result%? Why it's a variable for an integer number
that can take 0-65535 different values, usually in the range
-32768 to +32768, although with a bit of hassle we can get them
to range from 0-65535. A bit-twiddler however will see them
as 16 continous bit spaces in memory that can contain 16
different boolean states, but they can be even more than that!

Here goes:
Suppose that FN doSomethingDumb must return 2 pieces of
information - a boolean and a value. Providing that the value
is in the range 0-32768, you just calculate the return value
and then use the sign to set the boolean. Coming back from the
FN you would then test for these:

result% = FN doSomethingDumb( myValue%)
LONG IF( result% < 0)
 result% = ABS( result%)
 FN actOnResult( result%)
'   these 2 lines can even be simplified to one:
'   FN actOnResult( ABS( result%))
XELSE
 FN actOnResult( result%)
END IF

Second proposition you need to return 2 values, neither of
which will exceed 256.
At the end of FN doSomethingDumb you have your 2 values, so
it goes like this:

 result% = myValue1%<<8 'effectively multiplying by 256
                         'or 'pushing' up 8 bit positions
 result% = result% + myValue2%
END FN = result%

And when the values get back to the calling FN, you do the same
thing but in reserve:

result% = FN doSomethingDumb( myValue%)
myValue1% = result% AND &FF00 'the will 'mask out' the value in the low 
bytes
myValue1% = result%>>8        'pushing back down by 8 bit positions
                              'Of course this operation can be simplified
                              'but that's is left to readers to try.
myValue2% = result% AND &00FF 'just grab lowest 8 bits for the second 
value

You can even combine boolean values and numeric values! In this case
we have 2 numeric values 0-31 and a boolean state (true or false).
Again, in the FN doSomethingDumb FN

DIM result%
DIM myBoolean1%
DIM myBoolean2%
DIM myNumber1%
DIM myNumber2%

'... do the stuff here
'   now package for returning:
myBoolean1% = myBoolean1%<<5  'pushes up the value assuming that
                              '1=_true and 0=_false. If you use _zTrue
                              'then you must do an ABS(myBoolean1%) first.
myNumber1%  = myBoolean1% + myNumber1%
myBoolean2% = myBoolean2%<<5  'same comments as above
myNumber2%  = myBoolean2% + myNumber2%
result%     = ( myNumber1%<<8) +myNumber2%
END FN = result%

Then you reverse the operation to extract the info. (Again, I'll leave 
this
for you to try.)

Hope that this has given you some insights into using FNs in
more creative ways, and th epower of thinking of memory as a
line of shoeboxes that can be manipulated, rather than as fixed
numerical values. Have fun, and I hope that others will post
other 'fun' techniques.

jonathan
PS. this is typed from head, please check all code before
using as is, and if you find an error or an ambiguity, please post.


  



-------------------------------------------------------------
! "format utile"  studio de graphisme/graphic design studio !
!      32 bd de Menilmontant, 75020 Paris, France           !
!    phone +33 1 43 49 02 04 +++ fax +33 1 43 49 16 51      !
-------------------------------------------------------------
           *** coming soon to a browser near you ***
           <http://www.cybercities.com/formatutile>
-------------------------------------------------------------