Next Previous Up Top Contents Index

5 Integers

5.4 Using special arithmetic features

As noted in Section 5.3, the Generic-Arithmetic library provides an extensible protocol for adding specialized arithmetic functionality to your applications. By using the Generic-Arithmetic library alongside a special implementation library, you can make the standard arithmetic operations support number types such as big (64-bit) integers, or complex numbers.

This section provides an example of extending the basic Dylan arithmetic features using the Generic-Arithmetic library and the Big-Integers implementation library.

To use special arithmetic features, an a library's define library declaration must use at least the following libraries:

common-dylan
generic-arithmetic
special-arithmetic-implementation-library 

So for Big-Integers you would write:

define library foo
  use common-dylan;
  use generic-arithmetic;
  use big-integers;
  ...
end library foo;

Next you have to declare a module. There are three ways of using big-integer arithmetic that we can arrange with a suitable module declaration:

1. Replace all integer arithmetic with the big-integer arithmetic
2. Use both, with normal arithmetic remaining the default
3. Use both, with the big-integer arithmetic becoming the default

To get one of the three different effects described above, you need to arrange the define module declaration accordingly. To replace all integer arithmetic with big-integer arithmetic, include the following in your define module declaration:

use generic-arithmetic-common-dylan;

(Note that the module definition should not use the Big-Integers module. The Big-Integers library is used as a side-effects library only, that is, it is referenced in the library definition so that it will be loaded. Its definitions extend the Generic-Arithmetic library.)

If you replace all integer arithmetic with big-integer arithmetic in this way, there will be performance hits. For instance, loop indices will have to be checked at run-time to see whether a normal or big integer representation is being used, and a choice must be made about the representation for an incremented value.

You can take a different approach that reduces the cost of big-integer arithmetic. Under this approach you leave normal integer arithmetic unchanged, and get access to big-integer arithmetic when you need it. To do this, use the same libraries but instead of using the common-dylan-generic-arithmetic module, include the following in your define module declaration:

use common-dylan;
use generic-arithmetic, prefix: "ga/"; // use any prefix you like

This imports the big-integer arithmetic binding names, but gives them a prefix ga/, using the standard renaming mechanism available in module declarations. Thus you gain access to big arithmetic using renamed classes and operations like:

ga/<integer> 
ga/+
ga/-
ga/*
...

The operations take either instances of <integer> or ga/<integer> (a subclass of <integer>) and return instances of ga/<integer>.

Note that having imported the big-integer operations under new names, you have to use prefix rather than infix syntax when calling them. For example:

ga/+ (5, 4);

not:

5 ga/+ 4;

The existing functions like + and - will only accept <integer> instances and ga/<integer> instances small enough to be represented as <integer> instances.

Under this renaming scheme, reduced performance will be confined to the ga/ operations. Other operations, such as loop index increments and decrements, will retain their efficiency.

Finally, you can make big-integer arithmetic the default but keep normal arithmetic around for when you need it. Your define module declaration should contain:

use generic-arithmetic-common-dylan;
use dylan-arithmetic, prefix: "dylan/"; //use any prefix you like


Common Dylan and Functional Extensions - 31 Mar 00

Next Previous Up Top Contents Index