comp.lang.ada
 help / color / mirror / Atom feed
* How to Design an Application Programmers' Interface (API)
@ 2000-08-10  0:00 E. Robert Tisdale
  2000-08-10  0:00 ` Kaz Kylheku
                   ` (2 more replies)
  0 siblings, 3 replies; 38+ messages in thread
From: E. Robert Tisdale @ 2000-08-10  0:00 UTC (permalink / raw)


The class library developer writes library functions, perhaps professionally,
which other programmers will use to write application programs.
The application programmer is the person who actually writes programs,
perhaps professionally, and is not just another library developer.
The library developers and application programmers negotiate
an Application Programmers' Interface (or an Application Program Interface)
so that they can work more or less independently of each other.
Usually, this negotiation amounts to nothing more than
application programmers accepting one of the existing class libraries
which may or may not be implementations of an existing standard API.
(A standard API permits programmers to write portable applications
 even if the libraries themselves are not portable.)
The assumption is that there are just a few library developers
and many application programmers so that the cost of developing
and maintaining a library can be amortized over several applications.

An API specifies the Abstract Data Type (ATD)
which the library supports together with a language binding
for each of the supported computer programming languages.
The various language bindings may not necessarily resolve
to exactly the same objects in a library archive
because that is an implementation issue
which is best left up to the library developer.
Usually, the API does not specify interoperability
between programs and subroutines written in different languages.

The secret to designing a good API is abstraction.
The API should specify no more detail about the actual data representation
or algorithm implementation than is necessary to provide a practical API.
There is virtually no penalty for abstraction built into modern,
object oriented computer programming languages like C++.
Unfortunately, some C++ compilers still impose a penalty for abstraction
but there is usually a suitable workaround that is transparent
to the application programmer so the problem is manageable.
Older computer programming languages, such as Fortran 77, won't even permit
library developers to substitute synonyms for built-in types
let alone permit library developers to define new types
so abstraction can be very difficult to preserve.

A good API, like anything else, should be designed from the top down.
Now, of course, everyone should be aware that good engineering requires
several cycles of top down and bottom up design.
All top down design really means is that the first stroke is top down.
The design should begin with the abstractions
which are to be resolved in the implementation.
The first implementation should expose most of the practical difficulties
of the design which can be used to work back up
to eventually resolve problems with the original abstraction.
Some care should be taken to consider all possible
alternate data representations and algorithm implementations so that
the API does preclude any reasonable representation or implementation.

It is important to be very precise about the definition of the ADT.
Once the ADT is correctly and precisely identified,
designing the rest of the API is relatively straight forward.
A vague description of an ADT which is too general to implement efficiently
is probably better represented by two or more similar but distinct ADTs
each of which can be implemented efficiently.

The API should specify all of the functionality required to support the ADT.
This is almost as easy to do as it is to say for the classical ADTs
which are implemented in the standard C++ library -- list, queue, etc.
But it can be a nontrivial task for the ADTs
supported by a numerical class library for example.
There appear to be a very large number of functions
that operate on vector, matrix and tensor objects.
The API should specify all of this functionality
even if it doesn't require that library developers support all of it.
The reason is that application programmers are going to implement
unsupported functionality whether it is specified or not.
But, if it is specified, application programmers can, at least,
implement the functionality as specified by the API
so that other application programmers will be able
to more easily read, understand and maintain the application source code.
In other words, the API need not mandate everything that it specifies.
The API should mandate only that functionality
which is required to implement the all of the specified functionality
so that application programmers can write portable versions
of the specified functions to replace any missing functionality.
This liberates library developers to implement as much or as little
of the remaining functionality as they see fit.

Application programmers who write their own libraries
are at a natural disadvantage when it comes to designing an API
because they virtually always have a particular implementation in mind
and begin to code before they define the ADT precisely.
They only discover their mistake when they realize that
they need to change the data representation or algorithm implementation
and find themselves searching through their application source code
to find all of the references that need to be changed.

The API designer preserves abstraction by hiding the actual details
of the data representation and algorithm implementation
from application programs so that application programmers
don't accidently reference them directly.
These details are not necessarily secret.
They may be published in documents or even source code
but they should be distinguished (and separated if possible)
from the specification of the API.
C++ API implementations hide the details of the actual
data representation behind a simple private: or protected: label
and provide member functions to access them.
C API implementations use opaque data types to hide private data members.
C++ API implementations use inline functions to avoid the abstraction penalty.
C API implementations may be obliged to use preprocessor macros
to avoid the abstraction penalty.
Fortran 77 requires custom preprocessing to avoid the abstraction penalty.

API designers seldom take abstraction seriously enough.
Generally, it's a good idea to take advantage of existing
especially standard data types but it is seldom a good idea
to expose such implementation details to the application program.
Usually, simple synonyms are sufficient to provide the required abstraction.
For example,

        typedef float   Single;
        typedef double  Double;
        typedef int     Integer;
        typedef size_t  Size;

may permit programmers to write more portable application source code
if they use the synonyms instead of the built-in types.




^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2000-08-13  0:00 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-08-10  0:00 How to Design an Application Programmers' Interface (API) E. Robert Tisdale
2000-08-10  0:00 ` Kaz Kylheku
2000-08-10  0:00   ` E. Robert Tisdale
2000-08-10  0:00     ` vrml3d.com
2000-08-10  0:00       ` E. Robert Tisdale
2000-08-10  0:00       ` Tony T. Warnock
2000-08-10  0:00         ` Toon Moene
2000-08-10  0:00         ` Keith Thompson
2000-08-10  0:00           ` E. Robert Tisdale
2000-08-10  0:00             ` Keith Thompson
2000-08-10  0:00               ` E. Robert Tisdale
2000-08-10  0:00                 ` Keith Thompson
2000-08-11  0:00                   ` David Botton
2000-08-11  0:00                 ` David Gillon
2000-08-11  0:00                   ` Peter S. Shenkin
2000-08-10  0:00 ` Jack Klein
2000-08-11  0:00 ` E. Robert Tisdale
2000-08-11  0:00   ` Larry Kilgallen
2000-08-11  0:00     ` E. Robert Tisdale
2000-08-11  0:00       ` Larry Kilgallen
2000-08-11  0:00         ` E. Robert Tisdale
2000-08-11  0:00   ` Gautier
2000-08-11  0:00     ` E. Robert Tisdale
2000-08-11  0:00       ` Interfacing to Numerical Programming libraries (was: How to Design..) Larry Kilgallen
2000-08-12  0:00         ` Sam Hobbs
2000-08-12  0:00         ` E. Robert Tisdale
2000-08-12  0:00           ` tmoran
2000-08-12  0:00             ` E. Robert Tisdale
2000-08-11  0:00       ` How to Design an Application Programmers' Interface (API) Gautier
2000-08-11  0:00         ` E. Robert Tisdale
2000-08-13  0:00   ` E. Robert Tisdale
2000-08-13  0:00     ` Gregory Pietsch
2000-08-13  0:00       ` E. Robert Tisdale
2000-08-13  0:00         ` Brendan Sechter
2000-08-13  0:00         ` Larry Kilgallen
2000-08-13  0:00         ` Gregory Pietsch
2000-08-13  0:00           ` E. Robert Tisdale
2000-08-13  0:00     ` Larry Kilgallen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox