home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
apl
/
cap
/
read.me
< prev
Wrap
Text File
|
1993-12-24
|
31KB
|
836 lines
Copyright (C) 1992, 1993 by Thomas Glen Smith. All rights reserved.
For more information regarding the CAPLIB software package, contact -
Thomas Glen Smith
3154 West Shady Lane
Neenah, Wisconsin 54956
Telephone (414) 836-2543
Compuserve: 76207,3343
This program is produced by a member of the Association of Shareware
Professionals (ASP). ASP wants to make sure that the shareware
principle works for you. If you are unable to resolve a
shareware-related problem with an ASP member by contacting the member
directly, ASP may be able to help. The ASP Ombudsman can help you
resolve a dispute or problem with an ASP member, but does not provide
technical support for members' products. Please write to the ASP
Ombudsman at 545 Grover Road, Muskegon, MI 49442 or send a CompuServe
message via CompuServe Mail to ASP Ombudsman 70007,3536.
The CAPLIB APL Interpreter on this disk is distributed as a Shareware
program. Individual users may freely copy this disk and share it with
friends and family. Permission to make copies of excerpts from this
text for personal use is hereby granted. If you like CAPLIB APL and
intend to keep using it, please acquire a license by contacting
Thomas Glen Smith at the above address. The license fee for CAPLIB APL
is $30. When you register you'll receive a copy of the book
"CAPLIB - APL For Programmers in C" by Thomas Glen Smith.
The CAPLIB APL Interpreter also runs on COHERENT (Trademark of Mark
Wiliams Company), an operating system which incorporates much of the
functionality of UNIX. File CAP\COHERENT\CAPLIB.UST on this disk
contains a version of CAPLIB APL which runs on COHERENT. The same
subdirectory contains a READ.ME file with instructions on how to load
the software under COHERENT.
If you'd like to take advantage of APL facilities in your C programs,
you can do so with the CAPLIB C run-time library. The CAPLIB APL
Interpreter was written in C using this library.
Executable C programs developed by using CAP.LIB routines, other than
those intended to be used as APL interpreters, may be freely distributed
without further payment or other royalties. The CAP.LIB run-time library
may be distributed only as part of a compiled executable program.
The license fee for the CAPLIB C run-time library is $30.
Support Policy
While every effort is made to ensure the CAPLIB routines and
documentation are free from defects, your sole and exclusive remedy
will be limited to my efforts to fix the problem, or to my refunding
your purchase price for the CAPLIB software if I'm unable to fix it.
You can contact me by mail, or at the Compuserve address indicated
above.
I'll try to answer any questions pertaining to usage for a period of
not less than three months after you acquire one of the CAPLIB licenses.
After that, I'll still answer questions, if I can, and have the time.
But I don't intend this to be my life's work.
What is CAPLIB?
CAPLIB is an implementation of APL, as documented in IBM publication
GC26-3847-4, titled "APL Language", Fifth Edition, July 1978. It
contains an interpreter that lets you program directly in APL on a
standard IBM PC or compatible. To date it's been tested on DOS 3.3
4.01, and 5.00, with 1 megabyte of memory or more. The APL interpreter
loads in 210K, so there's no reason why it won't work on smaller
machines.
Once you've found the best way to solve a problem using the APL
interpreter, you may want to enhance performance by incorporating
that same logic in a C program using calls to routines in the CAPLIB
run-time library, which is available under a separate license. There
are over four hundred routines available. ANY SINGLE APL STATEMENT
INVOLVING STANDARD APL FUNCTIONS AND OPERATORS CAN BE DIRECTLY
TRANSLATED TO A SINGLE C LANGUAGE STATEMENT USING CALLS TO CAPLIB
ROUTINES.
The source programs for the entire CAPLIB package is also
available under a separate license.
Diskette Format
The content of this disk depends on which components of CAPLIB you've
ordered: The diskette contains these files in its root directory,
with the indicated license numbers:
- APL.EXE (License #1): APL interpreter (Shareware).
- APLF.BAT (License #1): Batch program you can elect to use with
EGA/VGA monitors to see the special set of APL characters (more
about this later in READ.ME). (Shareware).
- FONT8X16.EXE (License #1): Normal character set that APLF.BAT
restores when you're done using the APL interpreter. (Shareware).
- APLFONT.EXE (License #1): Special APL character set. (Shareware).
- HELP.APL (License #1): APL workspace that provides assistance to
you while you're using the APL interpreter (more about this later
in READ.ME). (Shareware).
- CAP.LIB (License #2): BLINK library with all the CAPLIB routines
you can call from your C programs. These are documented in the
book "CAPLIB: APL for Programmers in C," a copy of which you
should have received along with this diskette if you purchased
either license #2 or #3.
- \INCLUDE\ (License #2 and #3): Source which may be INCLUDEd in
your C programs. For license #2, this subdirectory will contain
5 files, and for license #3 it will contain 35 files.
- \SOURCE\ (License #2 and #3): For license #2, this subdirectory
will contain only 6 files, useful in debugging your C programs.
With license #3 you get 420 files in this subdirectory.
- \HANDBOOK\ (License #1): Here are nine APL workspaces containing
defined functions modeled after those listed in the "APL Handbook
of Techniques" published and copyrighted by IBM in April, 1978.
(Shareware).
Trying the APL Interpreter
To try the APL interpreter, make this diskette current, key "apl" and
press Enter. The interpreter will prompt you with "APL>". To stop the
interpreter and return to a DOS prompt, key ")off" and press Enter.
If you've used APL before and you're reading this for the first time,
you may think ")off" is a typographical error. It should read ")OFF"
since the APL symbol set doesn't include lower case letters. CAPLIB
maps the upper case letters in the APL symbol set to the lower case
letters of the PC keyboard.
There are also about 27 other symbols on a typical APL keyboard that
don't show up on the standard PC keyboard, and 19 symbols that are
composites, produced by keying one symbol, pressing the backspace key,
and overtyping with a second. There's also the underscored letters A
to Z. CAPLIB maps all these symbols to a standard PC keyboard.
There's a function that helps you with this mapping while you're using
APL. To use it, when you see the prompt "APL>" enter
")copy help helpgroup". When you see the "APL>" prompt again, try -
help 'I'
which will display the following:
I iota symbol, index generator, index of
I index generator, I5 is 1 2 3 4 5
I index of, 'abc ' I 'b c a' is 2 4 3 4 1
This is telling you that "I" represents the APL iota symbol, which
invokes two APL functions called "index generator" and "index of."
An example of "index generator" is
I5
which produces the string of numbers "1 2 3 4 5". An example of
"index of" is
'abc ' I 'b c a'
which produces the string of numbers "2 4 3 4 1" indicating the "b"
in 'b c a' is located in position 2 in 'abc ', " " (a space) is at
position 4, "c" at position 3, and so on.
Once you've done the ")copy help helpgroup" you can enter help 'x'
where x is any character on the keyboard, to get a description of
what that key represents in the APL symbol set. Just be sure you
surround the character in single quotes. Entering, for example -
help y
may get you an error message like, "59 - Operand not found where
expected during execute."
You can also use "help" to find out about specific APL functions.
Suppose you think you want to use the APL factorial function, but
you don't remember exactly how it works. You can find out by
entering -
help 'factorial'
which will display the following:
! factorial, !5 is 120
This is telling you that the exclamation point (!) invokes the
factorial function, and that !5 produces 120, which of course is
5 X 4 X 3 X 2 X 1, the standard factorial function learned in grade
school algebra.
Video Display of APL Symbols
If you invoke the APL command, the PC monitor shows the normal
keyboard characters as you press them. But if you invoke the APLF,
APL symbols are displayed. I prefer that "M" be displayed when I
press Shift and the "m" key, and "M" maps in my mind with no trouble
or confusion to the domino APL symbol. But if you want to see the
APL domino, iota, etc., use APLF.
APL Tutorial
This is a brief introduction to the APL language. A detailed
explanation is in the book "CAPLIB: APL for Programmers in C"
copyright 1992, by Thomas Glen Smith (that's me). You receive
a copy when you acquire a license for any of the three components
of the CAPLIB software package:
(1) The APL Interpreter.
(2) C Run-time Library.
(3) C Run-time Library source.
Most of us who claim to be programmers were introduced to the craft
with a procedure-oriented language such as BASIC, FORTRAN, PL/1, or
C. The keywords and syntax may differ from one to the next, but a
programmer uses similar logic with each of these languages to arrive
at solutions. Their operators typically deal only with one item at a
time, and one must define a loop to iteratively process arrays of
items. For example, this C program adds 5 numbers and prints the sum:
#include <stdio.h>
#include <stdlib.h>
main()
{
static double a[5] = {11.0, 22.1, 3.2, 43.5, 71.4};
double sum=0.0;
int i;
for ( i=0; i<5; i++ ) sum += a[i];
printf("sum = %5.2f",sum);
}
sum = 151.20
Contrast the above C program with the solution of the same problem in
APL:
+ / 22.1 3.2 43.5 71.4
151.2
First, of course, you'll notice the conciseness. There are pros and
cons to this. There's the obvious advantage of a smaller source to
maintain. But in a more complicated APL program, when it comes time
to make changes a few months after it was written, it can be difficult
to understand the intent of the program simply by reading the source.
You've heard of read-only memory? Some critics of APL refer to it as
the "write-only" language.
Be that as is it may, the real advantage of APL hasn't been pointed
out yet. Namely, that its structure is carried along with data, and
is removed from the program. Suppose we wanted to change the problem
to find the sum of six numbers instead of five. In our sample C
program we would need to change the "for" statement to test for i
less than 6 instead of 5. But in APL all we change is the data:
+ / 22.1 3.2 43.5 71.4 89.5
240.7
If you haven't programmed in APL, because of the simplicity of this
sample problem, you may not realize how significant this is, but
you'll find learning APL alters how you as a programmer solve
problems.
Overview of APL
APL consists of three fundamentals: arrays; functions; and operators.
Arrays are structured collections of data, either numbers or
characters. Functions accept arrays as arguments, and produce new
arrays as results. Operators accept both arrays and functions,
applying the functions in special ways, also producing new arrays
as results.
APL Arrays
Arrays are the means in APL for organizing and storing data. An array
can consist of either numeric or character data, not both. Arrays
have rank indicating the number of dimensions. Single items are
called scalars, and have rank 0. Vectors are zero or more items
ordered in a row, and have rank 1. A matrix has rows and columns, and
has rank 2. Higher ranked arrays are just called arrays.
Arrays are named and given data values with the assignment function,
which is a left arrow in standard APL, and the pound sign (#) in
CAPLIB:
" a becomes the scalar 3
a # 3
" b becomes the vector 1 3 5
b # 1 3 5
" c becomes the character vector 'abc'
c # 'abc'
" a becomes a new vector and is displayed
L # a # a + b
4 6 8
Several important concepts are demonstrated in the last APL statement
above:
-> APL statements are evaluated right to left, and there is no
operator precedence, such as multiplication being done before
addition.
-> APL arrays can change their data values, just like many other
programming languages, but what is more unusual is that they
can change their shape. In this case variable a changed from a
scalar of rank 0 to a vector or rank 1, dimension 3.
-> You can insert "L#" anywhere in an APL statement to display
results to that point. L is the caplib symbol for the APL quad
symbol.
APL Functions
Functions accept arrays as arguments, producing new arrays as results.
They can be either primitive or defined depending on whether they are
built in to the APL system, or defined by you. Defined functions are
the means by which you "program" in APL. Primitive functions can be
scalar or mixed.
Scalar Functions
Scalar functions apply to their arguments item-by-item, regardless of
their structure, and if they're dyadic (accepting two arguments),
they generally expect the arguments to be of identical rank and shape.
There is one exception to this rule: If one argument is a single item,
either a scalar or one-element vector, it will be replicated to match
the number of items in the other argument. Generally, scalar functions
yield results with shapes identical to their arguments. Addition,
multiplication, and division are examples of scalar functions. There
are only two scalar functions that accept character data arguments.
They are the comparisons equal and not equal.
"addition subtraction multiplication
1 2 3 + 4 5 6 1 2 3 _ 4 5 6 1 2 3 X 4 5 6
5 7 9 -3 -3 -3 4 10 18
"floor ceiling reciprocal
D -3.14 2.718 S -3.14 2.718 % 4 -5
-4 2 -3 3 0.25 -0.2
'abc' = 'axc' 'abc' ^= 'axc'
1 0 1 0 1 0
Mixed Functions
There can be two reasons why they might be called mixed functions.
First, where they're dyadic, the two arguments don't have to agree
either in shape or in data type. Usually the left argument is
numeric, giving instructions for manipulation of the right
argument, which can either be numeric or character.
"reshape shape
L # a # 2 3 R 1 2 R a
1 2 1 2 3
2 1 2
"index generator index of
I 5 'abcdef' I 'cad'
1 2 3 4 5 3 1 4
"take drop
3 Y 2 4 6 8 2 U 2 4 6 8
2 4 6 6 8
Operators
Operators accept both arrays and functions, applying the functions
in special ways, producing new arrays as results. There are five
operators:
1) Reduction: Denoted by a slash (/), reduction accepts as its
left argument a scalar dyadic function, and as its right
argument a numeric array. It applies the function between
adjacent items in the array. If v is a vector +/v produces
the sum of all elements in v.
2) Scan: Denoted by a backslash or slope (\), scan is related to
the reduction operator. It also accepts as its left argument
a scalar dyadic function, and as its right argument a numeric
array. The result is equivalent to the catenation of the
results of applying the scalar dyadic function using reduction
over successively longer selections from the right argument
The expression X\2 3 4 produces the result 2 6 24, where 2 is
the result of X/2, 6 is from X/2 3, and 24 is from X/2 3 4.
3) Axis: Operators such as scan and reduction described above are
first defined for vectors, and then applied to arrays of higher
rank as though they were sets of vectors defined along a
particular dimension. For example, a matrix has two dimensions,
rows and columns, and can be considered as a set of vectors
either running along each row or down each column. The axis
operator is denoted by brackets enclosing an expression which
yields the index of the dimension along which the vector set is
defined. For example, if m is a matrix, +/[1]m denotes
reduction down each column, and +/[2]m reduction across each
row:
L # m # 2 3 R I 6 +/[1]m +/[2]m
1 2 3 5 7 9 6 15
4 5 6
4) Inner Product: The dot (.) denotes inner product. Its arguments
are two scalar dyadic functions and two arrays. One form, m+.Xn,
is commonly called the matrix product of linear algebra:
L # m # 2 2 R 2 3 4 5 L # n # 2 3 R 5 + I6
2 3 6 7 8
4 5 9 10 11
m +.X n
39 44 49
69 78 87
5) Outer Product: Accepting a primitive scalar dyadic function and
two arrays as arguments, outer product applies the function
between all possible combinations of items from the left array
argument with items from the right array argument:
1 2 3 J.X 1 2 3 4 5
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
Workspaces
When you create named arrays and defined functions interactively in
APL, they're stored in memory in what is called the "active
workspace." Numerous workspaces can be stored on disk, any one of
which you can load into memory as the active workspace. You can
modify variables and defined functions while the workspace is in
memory, then save it back on disk. There are 16 APL System Commands,
all prefixed with a right parenthesis, for manipulating workspaces
and their content:
1. )clear -- Clears out the active workspace. Expunges all variables
and defined functions so the workspace is empty.
2. )copy wsname object [object...] -- The named object(s) are copied
from the specified workspace named "wsname" on disk into the active
workspace.
3. )drop wsname -- The workspace named wsname is deleted from disk.
4. )erase [object...] -- The named object are expunged from the active
workspace.
5. )fns [a] -- Displays a list of defined functions in the active
workspace, starting with the optional letter indicated by [a].
6. )group grpname [grpname] [object...] -- The list of objects are
grouped so they can be easily referenced by the single name
grpname.
7. )grp grpname -- Displays the membership of the named group.
8. )grps [a] -- Displays the groups in the active workspace, in
alphabetical order, optionally starting with the letter indicated
by "a".
9. )load wsname -- Workspace "wsname" is loaded into memory as the
active workspace.
10. )off -- Leave the interactive APL interpreter, and return to DOS.
11. )pcopy wsname object [object...] -- Identical in function to
)copy, except a named object will not be replaced if it already
exists in the active workspace.
12. )save [wsname] -- Saves the active workspace to disk with file
name "wsname.apl".
13. )si -- Displays the state indicator, showing halted defined
functions.
14. )sinl -- Same as )si, except local names are listed for each
defined function.
15. )vars [a] -- Displays a list of variables in the active
workspace, in alphabetical order, optionally starting with the
letter indicated by "a".
16. )wsid [wsname] -- If "wsname" is specified, it becomes the name
of the active workspace. Otherwise, the name of the active
workspace is displayed.
User Defined Functions
A defined function is created by you, and is the means whereby you
"program" in APL. It consists of a function header followed by one
or more APL statements. Here's one called "plus" that returns the
sum of its two arguments:
" Lcr lists a character representation of a defined function
Lcr 'plus'
res # l plus r
res # l + r
1 + 2 + 3 1 + 2 plus 3
6 6
The first thing in a defined function is always a function header,
which begins with a template describing the function name and
arguments. This is analogous to the function declarator that appears
at the front of a program written in C. The template has one of six
forms:
Type With Result Without Result
Dyadic r # x f y x f y
Monadic r # f y f y
Niladic r # f f
where:
-> f is the name by which the defined function is known.
-> r is the localized name of the variable that will contain the
result. At least once during each execution of the defined
function, an assignment must be made to this name.
-> x is the localized name of the left argument of a dyadic defined
function.
-> y is the localized name of the right argument of a dyadic or
monadic defined function.
After the template describing the function name and arguments, you
can optionally include a list, delimited by semicolons, of names to
be localized. For example, the function header -
a demo b;c;d;e
declares demo to be a dyadic function returning no value, with left
and right arguments a and b, and three localized variables c, d, and
e.
Branching
Defined functions can have numerous APL statements in them, normally
executed sequentially. You can change this order by inserting branch
statements, each comprised of a right arrow (this is a dollar sign
($) in the CAPLIB symbol set) followed by an expression yielding a
scalar or vector. An empty vector means no branch will occur.
Execution continues with the next sequential statement. Otherwise,
the integer part of the leftmost or only value designates the next
statement to execute, according to these rules:
-> All statements in a defined function are sequentially numbered,
the function header being 0, the next statement 1, and so on.
-> If the integer derived from the branch statement is negative, 0,
or greater than the largest statement number in the defined
function, execution of the function terminates.
State Indicator
)Si displays the state indicator, the stack of halted, i.e. suspended
and pendent, functions. Their names are listed in order, the most
recently halted first. Each is followed by the bracketed statement
number that was about to be, or was being, executed when the function
was halted.
Functions are halted either by an error, such as an attempt to divide
by zero, or by the stop control discussed below. They're called
suspended when this happens, and are flagged in the state indicator
list by *.
Pendent functions, those without * next to their names in the state
indicator, are there because they've invoked another function that
either got suspended, or became pendent by calling another function,
and so forth until one finally did get suspended.
When a function gets suspended you get control at the terminal. You
can enter pretty much any statement you like. You can clear functions
on the state indicator from the last to the preceding suspension by
entering a right arrow ($). Or you can branch anywhere in the topmost
suspended function by entering a right arrow followed by the statement
number to branch to.
You can resume execution at the point of suspension by branching to an
empty vector ($ I0), or to the line counter, Llc. This is a system
global variable that is a vector holding the current statement numbers
of the functions on the state indicator, in the same order, i.e., the
most recently halted leftmost.
Stop Control
For debugging purposes, you can stop any defined function and receive
control just before any particular statement gets executed. To stop
defined function demo before lines 5 and 9 are executed, for example,
enter the APL statement -
sHdemo # 5 9
You'll receive control in the localized environment of demo. If it
localized variables a and b, then you'll have access only to those
local instances. You can interrogate and change any variable you have
access to. You can resume execution at any statement n in demo by
entering $n, or you can terminate demo's execution by entering $0.
Trace Control
For debugging purposes, you can trace any statement in a defined
function. You'll receive a report on your display each time a
designated statement in a defined function is executed. To trace
lines 1 thru 5 in defined function demo, for example, enter the
APL statement -
tHdemo # I5
The function name, the number of the statement in brackets, and the
final value of the statement is displayed each time it is executed.
A branch statement is indicated by a right arrow ($ in CAPLIB)
followed by the number of the next statement to be executed.
Del Editor Sample Session
Part of the standard APL system is a component called the "Del editor".
It's rather crude by today's standards. It worked great when the only
terminals available were teletypes. This sample session begins by
creating a defined function called sum:
The APL interpreter prompts with "APL>". I tell it I want to enter the
del editor for function sum:
APL> Gsum
[1]
The editor generally prompts for input by displaying the bracketed
statement number it expects you to enter next. In this case it has
prompted me to enter statement [1]. Because the function is new, the
editor assumes I entered the function header when I entered "Gsum".
It thinks sum is going to be niladic without a returned value. That's
not the case, so I tell it I want to re-enter the function header by
keying [0]:
[1] [0]
The editor prompts me with [0] and I supply the new function header for
sum:
[0] z # sum x
The editor prompts me with the next sequential statement number, and I
respond with the statement:
[1] z # + / x
The editor prompts me with the next sequential statement number. I ask
to see the entire defined function:
[2] [L]
G z#sum x
[1] z#+/x
G
[2] G
APL>
The editor displays the entire function, placing a G in front of the
function header and after the last statement. It also lists bracketed
statement numbers at the left margin. Finally it prompts me again to
enter statement 2, to which I respond "G" to tell it I'm done editing,
and I'm once again prompted with "APL>".
Inserting a Statement
Suppose I want to add a comment to defined function sum telling what it
does:
APL> Gsum
[2] [0.1] " provides vector sums
[0.11] [L]
G z#sum x
[0.1] " provides vector sums
[1] z#+/x
G
[2] G
APL>
Deleting a Statement
Then I change my mind and decide to delete the comment, displaying the
entire function before and after:
APL> Gsum[L]
G z#sum x
[1] " provides vector sums
[2] z#+/x
G
[3] [H1]
[3] [L]
G z#sum x
[2] z#+/x
G
[3] G
APL>
Editing Statements
Now I'll use the statement editing capabilities to transform sum into
defined function mean:
APL> Gsum[L]
G z#sum x
[1] z#+/x
G
First there's the replacement of the function header:
[2] [0]
[0] z#mean x
[0.1]
Now to change statement [1] so it produces the vector means rather
than the sums:
[0.1] [1L0]
[1] z#+/x
Entering "[1L0]" above told the editor to display statement [1] with
the cursor positioned at the end of the statement, but one line lower
on the display. With standard APL, now you're expected to position
the cursor and key in letters or decimal digits indicating where you
want blanks inserted in the statement, and how many. Keying a "/"
means delete the character in the statement at that position. You can
use this if you want to, it'll work. But I just press Enter at this
point.
The editor responds by re-displaying the statement with the cursor
positioned on the same line at the right end of the statement. I
deliberately key an unmatched left parenthesis to get the editor to
issue the "unbalanced parenthesis" message and enter a special edit
mode which is not standard APL. In this mode:
-> The left and right arrow keys on the PC keyboard move the cursor
to new positions in the statement, without changing anything.
-> The Backspace key moves the cursor left, and at the same time
deletes a character.
-> Pressing any of the alphanumeric keys, e.g. ``K'', inserts that
character in the statement at the cursor position, and the cursor
is shifted right one position.
[1] z#+/x(
[1] z#+/x(
^ unbalanced parentheses
[1] z#(+/x)%-1Y1,Rx
[2] G
APL>
Now let's try the new mean function to see if it works:
APL> Gmean[L]G
[0] G z#mean x
[1] z#(+/x)%-1Y1,Rx
G
APL> mean 1 2 3 4 5
3
APL> mean 5
5
Executing APL statements from a DOS file.
You can execute APL statements other than through the keyboard by
first storing them in a text file, named "stmts.tex" for example,
then using DOS pipelining:
apl < stmts.tex
Incidentally, you can redirect the output to a printer in the same
fashion:
apl < stmts.tex > prn
Be sure to conclude your text file with an )OFF statement.
This concludes this read.me file.