====================================================
            ====        Guidelines for APL Libraries        ====
            ====================================================

This document exists in 2 versions: this version (which is supposed to be
useful for all kinds of APL interpreters) and Library-Guidelines-GNU-APL.html
which contains additional information that is only relevant for users of
GNU APL.

A section may be empty if the other version of this document contains only
information relevant for GNU APL.

0. Terminology
==============

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
   document are to be interpreted as described in RFC 2119 [RFC2119].

1. Libraries
============

For the purpose of this document, a library shall be code in any language
(but primarily APL and C/C++) that is made available by individual developers
to a larger community.

This document states requirements on such libraries in order to make them
useful and usable. Different requirements may be in conflict, and then the
following order (in decreasing relevance) shall be applied to resolve that,
but in a pragmatic way:

A. User friendliness and usability
B. Portability
C. Clear Code structure
D. Performance
   ...

1.1 Intended audience
---------------------

APL programmers.

1.2 How Libraries may be used
-----------------------------

The standard way of using a library of APL code SHALL BE a simple
single command such as:

      )COPY lib

However, the same library could be used in completely different ways as well:

- published on a web page
- cut-and-paste (xterm middle mouse button, or CTRL-C / CTRL-V) between
windows or browsers

The file format MUST support all use cases above. This rules out file
formats that use non-portable encodings.

1.3 Library structure at APL Level
----------------------------------

An APL script file consists of several lines of APL code that is executed
line-by-line when )LOADed or )COPYd. An APL library uses the same format but
should have a particular structure in order to be useful as a library:

A. )COPY of other libraries

B. Definition of APL functions

C. Initialization of global variables

A APL script file often has the same order, but may then call one or more
of the defined functions, and possibly )OFF at the and of the script. This
SHOULD be avoided in libraries because it could bring the workspace into a
state that is not foreseen by other libraries.

What is acceptable after C. is the execution of functions that check the
)COPYd libraries (dependencies, version numbers, etc,). Such check functions
MUST NOT, however print anything, except when errors are detected. This
is because a library may be )COPYd several times

1.4 Portability
---------------

We foresee 3 levels of portability for libraries that contain APL code:

L1: ISO portability. This means that the APL uses only APL constructs and
    commands defined in the ISO standard or are present (and identical) in
    all major APL interpreters.

L2: basic portability: This means that non-standard functions can be used in
    APL code but only via wrapper functions in another library called 'base'.
    Portability is achieved by only porting the 'base' library to another
    interpreter and then all libraries with basic portability will run on
    that interpreter. This more or less means that all non-standard ⎕-functions
    are wrapped, e.g. ⎕CR becomes ∆CR, etc.

L3: Interpreter specific portability: These libraries can only be used with 
    APL interpreters of the same vendor because they heavily use extensions
    of the ISO standard or because they are used to implement missing
    functions in the interpreter of that vendor.

1.4.1 The base library
----------------------

The 'base' library is a L3 library that is created as a means to simplify the
use of the same L2 library on otherwise incompatible APL systems. The typical
difference between such systems is the number of ⎕-functions and, less often,
between ⎕-variables.

The idea is that instead of using a non-portable ⎕-function say ⎕XYZ in the
library, one would use ∆XYZ and define ∆XYZ in the base library. Porting
the base library once to a different APL interpreter would then cause all
L2 libraries to function unmodified on the new interpreter.

The base library MUST define wrapper functions for all ⎕-functions and 
⎕-variables that differ from the corresponding functions in the ISO standard.
Such ⎕-functions are either completely new, or extend existing ⎕-functions
(additional arguments, dyadic ⎕-function in the interpreter vs. monadic
⎕-function in the standard etc.

The base library MAY define wrapper functions even if no differences exist;
this is for handling cases where it is not clear if some behavior is standard
or not. In these cases the designer of the library shall decide whether the
wrapper or the original function is used.

The names of ⎕-functions are usually case insensitive while user defined
functions are not. This is used in the following name convention for wrapper
functions:

The wrapper function for a ⎕-function, say ⎕FUN, shall be ∆FUN (and not
base∆FUN as for other libraries. This is to make changing the names simple.

A ⎕-variable, say ⎕VAR, has two wrapper functions ∆VAR and ∆var. The uppercase
variant is a niladic function for referencing ⎕VAR while the lowercase
variant is a monadic function setting ⎕VAR. Uppercase was chosen because it
is the form used historically and in the ISO standard. Read-only system
variables only have the ∆VAR wrapper function.

Another library foreseen is a 'meta' library that contains functions related
to library managements (dependencies, revision numbers, copyrights etc).
'meta' is a L2 library (and as such must not )COPY a L3 library).
Generally speaking, a L1 library must not depend on a L2 or L3 library and
a L2 library must not depend on a L3 library.

The base library SHOULD be maintained by the vendor of the target
APL interpreter or by users of that interpreter.

1.4.2 The meta library
----------------------

A library MUST contain a certain amount of meta information in order to be
used by e.g. packet managers. For the developer of a library this SHALL NOT
create too much burden. Therefore a meta library shall be developed that
reduces the extra work of the developer to the bare minimum, such as providing
contact information, bug report email, and licenses.

The meta library shall be a L1 library (i.e. full portability) and
it shall also contain functions that check if all meta information needed
is in a library.

A library, say FOO, shall contain a niladic function FOO⍙metadata that
returns meta information (see 2.2 below for an explanation). For example:

      SQL⍙metadata
 Author        Elias Mårtenson                       
 BugEmail      bug-apl@gnu.org                       
 Documentation                                       
 Download      https://github.com/lokedhs/apl-sqlite 
 License       LGPL                                  
 Portability   L3                                    
 Provides      SQL                                   
 Requires                                            
 Version       1.0     

The result of FOO⍙metadata is a nested N by 2 matrix of property names and
values.  Property names and values shall be simple text strings. The
FOO⍙metadata function is used by package managers to extract information
about the library.

A library called meta may be provided that contains functions for checking
meta information and for preparing it in different formats such as HTML for
listing libraries, packet managers, and other programs.

A library need not )COPY the meta library itself; the meta library is intended
to be used by programs like package managers and for web pages listing
packages and their properties.

The details need to be worked out...

1.5 Library types
-----------------

We expect the following kinds of code:

A. pure APL libraries
B. mixed APL/C/C++ (and possibly other languages).

In A. the focus is on APL and this will most likely be a L2 or L1 library.
In B. the APL code will be a thin wrapper level. This will be a typical L2
lib.


2. Naming Conventions
=====================

The library concept described in this documents uses a number of naming
conventions as follows.

2.1 Library name
----------------

The library name SHALL be short, but still long enough to be easily remembered
by the user. For example:

SQL	for the SQL interface
FIO	for the FILE_IO functions
FOO	for an example library used in the following.
...

2.2 APL names
-------------

In APL the functions and global variables of library 'foo' shall be named
foo∆function_name or foo∆variable_name. Local variables, function arguments, 
and return values SHALL have the usual short names without the foo∆ prefix.

A second prefix foo⍙ is used for functions related to meta information. These
meta functions are not used by library user but by the management of libraries
as explained further down.

2.3 Library Filename
--------------------

The APL code for library foo MUST be contained in a file called foo.apl.

2.4 Library Directories
-----------------------

Libraries can live in one of 10 directories that are selected by a 'library
reference number' from 1-9, and a missing library number means 0. The
library reference number is an optional argument of the )LOAD, )COPY and
)SAVE commands like:

      )COPY 4 foo

We propose that the first 3 library reference numbers, i.e 0-2,  SHOULD be
left for the user (to organize them in a user/group/all fashion) and that the
next 3 library numbers, i.e. 3, 4, and 5 resp, SHALL be used for L1, L2, and
L3 libraries.


It is important, that the library reference numbers that are used
follow the same scheme so that unneccessary errors caused by wrong library
reference numbers in )COPY commands are avoided. The designer of a )COPYd
library MUST propose a library reference number to be used, so that other
libraries that are build on top of some library will know where to find it.

2.5 Library initialization
--------------------------

The ')COPY 4 foo' command shall load all components of the library and perform
the necessary initialization. It SHALL also perform dependency checking as
needed, so that the user can use the functions installed by the library without
any additional actions.

The )COPY command can handle .apl files (i.e. other libraries) recursively.
Therefore a library MUST load all libraries that it depends on.

2.6 Double Inclusion
--------------------

The library MUST BE stateless, so that loading the same library twice
is possible.

2.7 Library Components
----------------------

-

3. Coding Conventions
=====================

3.1 C1 library components are intended be )COPYd at the beginning of the
    user code.

3.2 The 'base' and 'meta' libraries SHALL )SIC so that subsequent creation of
    functions is guaranteed to succeed.

3.3 A library must not (permanently) change the default values of system
    variables and must not create global objects with names other than foo∆...

(more to come...)

4. Documentation
================

The library MUST contain sufficient documentation describing how to install and use the library. For simple libraries this can be a few lines (say up to 30)
of APL comments at the beginning of the library. For longer texts a separate
UTF-8 encoded text file named foo.text shall be used.

Formats such as .PDF or Windows .doc SHALL be excluded because they tend to
make cut-and-paste from the, hopefully many, examples in the text difficult.

(more to come...)

5. File format for C1 Library Components
========================================

After having looked at different existing exchange formats, is looks like
UTF8-encoded text files is the way to go to achieve the top-level
requirements for C1 library components (i.e. for APL source files).
Binary formats are slightly more efficient, but are lack cut-and-paste
facilities.

5.1. Encoding
-------------

The library shall be a text file containing only valid Unicode characters
that are UTF-8 encoded.

The first two characters of the text file MUST be #! for C3 components
and ⍝! for C2 and C1 components

5.2. Correctness
----------------

The library shall contain correct APL code in the sense that it can be
)COPYd into an APL workspace without errors.

APL Commands MAY be used, in particular )COPYing of other libraries.
L1 library must only use commands defined in the ISO standard. Commands
that MAY alter the default variables permanently (such as) LOAD) MUST NOT
be used,

5.3 Representation of APL values
--------------------------------

Generally speaking any sequence of APL expressions that produces a given APL
value can be used in a library. For libraries originated in GNU APL, the
)DUMP command or 10 ⎕CR can be used to create such expressions without
side-effects.

For libraries originated in other APL interpreters other functions may exist
that have the desire effect of producing APL code that creates variables with
a given value.

5.4 Representation of user-defined APL Functions
------------------------------------------------

There are currently 3 methods to create a user defined function in GNU APL:

A. named direct functions, e.g. PLUS ← { ... } , or

B. ⎕FX,                    e.g. ⎕FX 'Z←A PLUS B' 'Z←A + B', or

C. The ∇-editor,           e.g. ∇Z←A PLUS B
                                 Z←A + B
                                ∇

Of these,
A. is not portable because direct functions are non-standard.
B. is difficult to read if a function gets longer,

Therefore method C. MUST be used for user-defined APL functions.


6. Packaging and Storing of Libraries
=====================================

6.1 Location
------------

Libraries are stored on the Web, either as part of the GNU APL project
at gnu.org or at some other place.

Libraries stored as part of the GNU APL project MUST obey the relevant
GNU policies (see e.g. www.gnu.org/prep/maintain/maintain.html,
www.gnu.org/server/standards/README.webmastering.html)
and MUST follow the guidelines in this document.

Libraries stored elsewhere SHOULD follow the guidelines in this document.

6.2 License and Copyright
-------------------------

The GNU LGPL license is recommended for all Libraries related to GNU APL.

Libraries stored as part of the GNU APL project MUST use a license that
is compatible with the GNU GPL or with the GNU LGPL. They MUST provide
valid copyright information identifying all non-trivial contributors.

Libraries stored elsewhere SHOULD NOT limit the freedom of others to use
the code in the library.

6.3 Central Web Page
--------------------

The GNU APL project SHOULD provide a web page that contains links to
libraries and other code related to GNU APL.

(more to come...)

7. References
-------------
   [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
             Requirement Levels", BCP 14, RFC 2119, March 1997.