A Quick Tour of GNU APL

1 Document Conventions
1.1 The Structure of the GNU APL Documentation
1.2 Conventions in This Document
2 Starting and stopping the APL interpreter
3 APL Statements
3.1 Constants (Literals)
3.1.1 Scalar Constants
3.1.1.1 Scalar Text Constants
3.1.1.2 Numeric Scalar Constants
3.1.2 Vector Constants
3.1.3 Mixed Constants
3.1.4 Nested Constants
3.1.5 Multi-Line Strings
3.1.6 Summary and Remarks
3.2 APL Names
3.2.1 User-defined Names
3.2.2 Names of System Functions and System Variables
3.2.3 Names of Primitive APL Functions
3.3 Functions and Operators
3.3.1 Niladic Functions
3.3.2 Monadic Functions
3.3.3 Dyadic Functions
3.3.4 Monadic Operators
3.3.5 Dyadic Operators
3.4 General APL Values
3.4.1 Reshape and Shape: ⍴
3.4.2 Catenate and Ravel: , and ⍪
3.4.3 Universal Character Set (monadic ⎕UCS)
3.4.4 Construction of arbitrary simple values
3.4.5 Construction of arbitrary nested values
3.4.6 Displaying the structure of values
3.4.7 Vector Notation versus Catenation
3.4.8 Scalar Extension
3.4.9 List of Built-in Scalar Functions
3.4.10 List of Other Built-in Functions
3.4.11 List of Built-in Monadic APL Operators
3.4.12 List of Built-In Dyadic APL Operators
3.4.13 Functions and Operators with Axis Argument
3.4.14 System Functions
3.4.14.1 Z ← ⎕AF B : Atomic Function
3.4.14.2 Z ← A ⎕AT B : Attributes
3.4.14.3 Z ← A ⎕CR B : Character Representation
3.4.14.4 Z ← ⎕DL B : Delay
3.4.14.5 Z ← A ⎕DLX B : Donald Knuth's Dancing Links
3.4.14.6 Z ← A ⎕EA B : Execute Alternate
3.4.14.7 Z ← A ⎕EB B : Execute Both
3.4.14.8 Z ← ⎕EC B : Execute Controlled
3.4.14.9 Z ← ⎕ENV B : ENvironment Variables
3.4.14.10 Z ← A ⎕ES B : Event Simulate
3.4.14.11 Z ← ⎕EX B : EXpunge
3.4.14.12 Z ← A ⎕FFT B : Fast Fourier Transform
3.4.14.13 ⎕FIO[X] B : File I/O functions
3.4.14.14 Z ← ⎕FX B : FiX
3.4.14.15 Z ← ⎕GTK B : Gtk GUI
3.4.14.16 Z ← A ⎕JSON B : JSON parser
3.4.14.17 Z ← A ⎕MAP B : MAP (replace) ravel elements
3.4.14.18 Z ← ⎕INP B : INPut from script
3.4.14.19 Z ← ⎕NA B : Name Association
3.4.14.20 Z ← ⎕NC B : Name Class
3.4.14.21 Z ← A ⎕NL B : Name List
3.4.14.22 Z ← A ⎕PLOT B : Plot a Value
3.4.14.23 Z ← A ⎕PNG B : Process PNG files and Pixel Images
3.4.14.24 Z ← A ⎕RE B : Regular expression
3.4.14.25 Z ← A ⎕RVAL B : Random APL value
3.4.14.26 Z ← [A] ⎕SI B : State Indicator
3.4.14.27 Z ← ⎕SQL[CMD] B : SQL functions
3.4.14.28 Z ← ⎕SVC B : Shared Variable Control
3.4.14.29 Z ← ⎕SVO B : Shared Variable Offer
3.4.14.30 Z ← ⎕SVQ B : Shared Variable Query
3.4.14.31 Z ← ⎕SVR B : Shared Variable Retraction
3.4.14.32 Z ← ⎕SVS B : Shared Variable State
3.4.14.33 Z ← [A] ⎕STOP B : STOP vector
3.4.14.34 Z ← A ⎕TF B : Transfer Form
3.4.14.35 Z ← ⎕XML B : XML parser
3.4.14.36 Z ← ⎕TRACE B : TRACE vector
3.4.14.37 Z ← ⎕UCS B : Universal Char Set
3.5 Variables
3.5.1 The Variables ⎕ and ⍞
3.5.1.1 Input and Output with ⍞
3.5.1.2 Input and Output with ⎕
3.5.1.3 ⎕ Input in Application Programs
3.6 Indexing
3.7 Execution of APL Statements
3.8 Defined Functions
3.8.1 Function Header
3.8.1.1 Creating and displaying defined functions: ⎕FX and ⎕CR
3.8.1.2 Result Specification
3.8.1.3 Local Variables
3.8.1.4 The Del Editor
3.8.1.5 Function Body
3.8.2 How Functions and Operators are Evaluated
3.8.3 Branching
3.8.3.1 Labels
3.8.3.2 Computed Branch (inside a function)
3.8.3.3 Computed Branch (outside a function)
3.8.3.4 Escape (Unwind)
4 Commands
4.1 Standard Commands
4.1.1 )CLEAR
4.1.2 )COPY
4.1.3 )COPY_ONCE
4.1.4 )DROP
4.1.5 )ERASE
4.1.6 )FNS
4.1.7 )LIB
4.1.8 )LOAD
4.1.9 )NMS
4.1.10 )OPS
4.1.11 )SAVE
4.1.12 )SI
4.1.13 )SIC
4.1.14 )SINL
4.1.15 )SIS
4.1.16 )VARS
4.1.17 )WSID
4.2 IBM APL2 Commands
4.2.1 )CHECK
4.2.2 )CONTINUE
4.2.3 )HELP
4.2.4 )HOST
4.2.5 )IN
4.2.6 )MORE
4.2.7 )OUT
4.2.8 )OFF
4.2.9 )PCOPY
4.2.10 )PIN
4.2.11 )RESET
4.2.12 )SYMBOLS
4.3 Additional GNU APL Commands
4.3.1 )DUMP
4.3.2 )DUMP-HTML
4.3.3 )HIST
4.3.4 )LIBS
4.3.5 )QLOAD
4.3.6 )VALUES
4.3.7 ]BOXING
4.3.8 ]COLOR
4.3.9 ]DOXY
4.3.10 ]EXPECT
4.3.11 ]KEYB
4.3.12 ]LOG
4.3.13 ]NEXTFILE
4.3.14 ]OWNERS
4.3.15 ]SVARS
4.3.16 ]SYMBOL
4.3.17 ]USERCMD
4.3.18 ]XTERM

A Quick Tour of GNU APL

March 4, 2024, SVN version 1760


Please report errors in this document to bug-apl@gnu.org

Copyright (©) 2013-2024 Dr. Jürgen Sauermann and friends.
This document is part of GNU APL and may be distributed under the terms of
the GNU Free Documentation License, see http://www.gnu.org/licenses/fdl.html

1 Document Conventions

1.1 The Structure of the GNU APL Documentation

GNU APL is shipped with different kinds of documentation for different purposes to be used at different times:
  1. A number of README files in the top-level directory. These files shall help with specific issues in the configuration of the interpreter, i.e. before the interpreter is compiled and/or after it is installed.
  2. man apl (in a terminal window) displays a list of all command line options understood by GNU APL.
  3. The )HELP command of the interpreter:
  4. This document (Quick Tour). It is a little more detailed, with a focus on examples. This is supposedly the best starting point for readers that are new to APL in general or to GNU APL in particular.
  5. info apl (in a terminal window). More detailed with a focus on only GNU APL specific features that are not available in, or differ from, standard APL.
  6. A number of files in the HOWTOs directory. These files describe some of the non-trivial GNU APL system functions.
All documentation is available on the local machine after GNU APL was successfully installed, and some of it is also available online via the GNU APL home page https://www.gnu.org/software/apl.

1.2 Conventions in This Document

Keyboard input is rendered in blue and the response from the GNU APL interpreter is black like this:
      This is what you type on the keyboard
and this is the response you get for correct input

      1+    ⍝ In contrast, APL ERROR messages are shown in red:
SYNTAX ERROR
      1+
      ^^
Error messages from the interpreter are shown in red. This coloring of input, output, and error lines above is the default, but it is possible to change the colors, or (e.g. if GNU APL is run as a script) to disable the colorization completely.

2 Starting and stopping the APL interpreter

APL is an easy-to-learn language. This quick start manual is an introduction to APL in a few simple steps. We assume that you are using GNU APL and that you have installed it according to the README files that came with it.

The APL interpreter is a normal program and is started like that: by entering its name in a shell (preferably bash).
$ apl
                    ______ _   __ __  __    ___     ____   __ 
                   / ____// | / // / / /   /   |   / __ \ / / 
                  / / __ /  |/ // / / /   / /| |  / /_/ // /  
                 / /_/ // /|  // /_/ /   / ___ | / ____// /___
                 \____//_/ |_/ \____/   /_/  |_|/_/    /_____/

                        Welcome to GNU APL version 1.8

                Copyright (C) 2008-2022  Dr. Jürgen Sauermann
                       Banner by FIGlet: www.figlet.org

                This program comes with ABSOLUTELY NO WARRANTY;
                         for details run: ./apl --gpl.

     This program is free software, and you are welcome to redistribute it
         according to the GNU Public License (GPL) version 3 or later.



The interpreter prints a start-up banner like that shown above and then enters an endless loop which APL programmers refer to as immediate execution mode and others as REPL (an abbreviation for Read-Evaluate-Print-Loop).

In immediate execution mode the interpreter reads one input line, either interactively from the user, or from a file if GNU APL is run as a script. It then processes (or Evaluates in REPL) the input line and prints some result output (which may be empty for some input lines). Depending on the details of the processing of the line entered, the interpreter will either: The following state machine describes this top-level behavior of an APL interpreter, and some user inputs that trigger mode changes:
   
                                ┌───────┐
                                │ Start │
                                └───────┘
                                    ↓
                                    ↓
                   ╔═══════════════════════════════╗      )OFF      ┌──────┐
         → → → → → ║   Immediate Execution Mode    ║→ → → → → → → → │ EXIT │
        ↑          ║        (Read in REPL)         ║                └──────┘
        ↑          ╚═══════════════════════════════╝
        ↑             ↓        ↑    ↑           ↓
        ↑             ↓       ^C    ↑           ∇ (enter definition mode)
        ↑             ↓        ↑    ↑           ↓
        ↑   ╔════════════════════╗  ↑  ╔═════════════════╗
        ↑   ║   Execution Mode   ║  ↑  ║ Definition Mode ║
        ↑   ║ (Evaluate in REPL) ║  ↑  ║   (∇-editor)    ║
        ↑   ╟────────────────────╢  ↑  ╚═════════════════╝
        ↑   ║  (Print in REPL)   ║  ↑           ↓
        ↑   ╚════════════════════╝  ↓           ∇ (leave definition mode)
        ↑             ↓             ↓           ↓
         ← ← ← ← ← ← ←               ← ← ← ← ← ←
   
In the first case, i.e. the interpreter remains in immediate execution mode, the whole process starts over again; the next line is read, processed, printed, and so on. The second case (leaving immediate execution mode) is explained in a later chapter. The first non-blank character of the line entered in immediate execution mode determines what happens next: The most important command at the moment is )OFF which ends the apl interpreter:
      )OFF
Goodbye.
$
Pressing control-C or control-D (i.e. the standard way to end programs) merely stops the execution of the current APL statement in execution mode, but does not end the interpreter. This behavior is similar to a shell where control-C stops the current program but does not exit from the shell.

3 APL Statements

APL statements are constructed from: Several statements on the same line are separated by the APL character ◊ (called Diamond). Note that different statements on the same line are executed from left to right while each statement is evaluated from right to left. Before discussing the execution of statements we will introduce their components, i.e. constants and names.

3.1 Constants (Literals)

Constants, also called literals, are used in APL statements for denoting fixed values.

3.1.1 Scalar Constants

The simplest constants are scalar constants, similar to atoms in Chemistry. From these scalar constants more complex constants can be created. There are also scalar APL values which are not constants; a definition of the term scalar will be given later. For the moment think of a scalar as a single data item.
3.1.1.1 Scalar Text Constants
The simplest scalar constants are scalar text constants. A scalar text constant defines a single character.
As we will discuss in more detail later, if you enter a constant (and nothing else) in immediate execution mode then the interpreter will transmit it to its output, although in a slightly different fashion.
A scalar text constant (aka. a single character) is entered by enclosing the character in single quotes. The character A, for example, is entered as 'A' and the interpreter answers by printing A but removing the quotes around it:
      'A'
A
The quote character itself is entered by doubling it inside the quotes that enclose it:
      ''''
'
3.1.1.2 Numeric Scalar Constants
A numeric scalar constant is a single number. The simplest numeric scalar constant is an integer, entered as a sequence of decimal digits:
      42
42
Fractional numbers are entered with a decimal point and a fractional part:
      42.5
42.5
The integral part can be omitted:
      .5
0.5
An optional scaling by a power of 10 (aka. scientific notation) can be applied with the character E, followed by the exponent. The E is case insensitive, therefore e will also work:
      42.5E3
42500
      42e3
42000
Negative numbers use a leading ¯ (Overbar); a minus sign is NOT the sign of a number but a function that negates a value. The result is often the same, but you should always use the overbar for negative numbers:
      ¯42.5E3
¯42500
The exponent in scientific notation can also be negative (in this case using - gives a different result):
      42.5E¯3
0.0425
      42.5E-3
VALUE ERROR
      42.5 E-3
           ^
The error in the second statement above occurs because:
  1. in APL the minus sign (i.e. - as opposed to ¯) is a primitive function and never part of a number, and therefore
  2. the E is not an exponent belonging to 42.5. Instead E is taken as the name of a variable (which does not exist in this example) and that causes the error. Using - instead of ¯ is a frequent mistake made by APL beginners.
Complex numbers can be entered in three different formats. The native format (native because it is the format used by the interpreter when printing complex numbers) is to specify the real and imaginary parts of a complex number separated by the letter J (or j):
      3J4       ⍝ a complex number of magnitude 5
3J4
      0.6j0.8   ⍝ the same, but scaled to magnitude 1
0.6J0.8
One alternative format is to specify the number as its magnitude and its angle in degrees (from 0° to 360°), separated by the letter D or d (which stands for "degrees"). Since arccos(0.6) = 53.130102354, we get the same complex numbers:
      5D53.130102354   ⍝ magnitude 5, angle 53.130102354°
3J4
      1d53.130102354   ⍝ the same, but scaled to magnitude 1
0.6J0.8
The other alternative format is to specify the number as its magnitude and its angle in radians (from 0 to 2π), separated by the letter R or r (for "radians"). Since 53.130102354 π ÷ 180 = 0.927295218 we get the same numbers:
      5R0.927295218   ⍝ magnitude 5, angle 0.927295218 radians
3J4
      1r0.927295218   ⍝ the same, but scaled to magnitude 1
0.6J0.8
Please keep in mind that whitespace characters (space, tab, etc.) are NOT permitted in numbers.

3.1.2 Vector Constants

Vector constants are created by writing several scalar constants on the same line, separated by one or more spaces between them. A single complex number is a scalar even if has two components (its real and imaginary parts). Multiple separating spaces between scalars are treated like single spaces:
      1   2 3
1 2 3
      'A' 'B' 'C'
ABC
Sequences of character scalars can be written with quotes around the sequence rather than quotes around each character. The rules for scalar character constants apply here as well:
      'ABC'
ABC
      'A''B''C'
A'B'C
      "A'B'C"
A'B'C
You cannot enter numeric vector constants with less than two elements because numeric vector constants with one element would be a numeric scalar constant, and numeric vector constants with no elements would be completely empty. You can enter an empty character vector constant (a vector with no elements) like this:
      ''

   
      ""
   
You normally cannot enter character vector constants with one element for the same reason as for numeric vector constants: it would be a scalar constant rather than a vector. This can become cumbersome when dealing with text; if the length of a character sequence is one then the text is a scalar, otherwise it is a vector. For this reason GNU APL provides a non-standard extension using double quotes instead of single quotes. This extension has slightly different and sometimes more convenient rules than texts in single quotes: Examples:
      "A"   ⍝ 1-element vector
A
      "'"   ⍝ a quote (')
'
      "A\"B\\C"   ⍝ 'A', double quote, 'B', backslash, 'C'
A"B\C
Finally, in the old APL1 (ISO 8485 standard) there was no way to express an empty numeric vector and one had to use expressions like ⍳0 or 0⍴0 for them. In modern interpreters, however, the symbol may be used to denote an empty numeric vector (i.e. of length 0). In APL1 empty numeric vectors were often expressed as '', frequently as ''⍴V to get the first item of a vector or matrix into a scalar. That worked, but these days one would use the cleaner ⍬⍴V instead.

3.1.3 Mixed Constants

The first APL interpreters (and the first APL standard, ISO 8485) only allowed constants and values whose components were either all numeric scalars, or all character scalars. The examples given so far were of that kind. The current APL standard, ISO 13751, also allows a mix of characters and numbers in constants and values, for example:
      1 2 'A' 'B' 3 4
1 2 AB 3 4
Such values are called mixed.

3.1.4 Nested Constants

The vector constants discussed so far were simple, which means that their components were (numeric or character) scalars. Since ISO 13751, another APL value can be used instead of a scalar. Such constants or values are called nested. The nested components of constants are vectors that are either quoted texts (aka. strings) or, if numeric, surrounded by parentheses instead of quotes:
      1 2 'AB' 3 4   ⍝ (nested) string 'AB'
 1 2 AB 3 4 
      1 2 (10 11) 3 4     ⍝ nested numeric vector (10 11)
 1 2  10 11  3 4 
In the normal output formatting of APL like above, the nesting of items is displayed as additional blanks which makes it sometimes difficult to recognize the exact nesting structure. The quotes and parentheses that group the items of a nested literal on input are replaced by blanks on output. That blurs the output, in particular when the nesting becomes deeper (i.e. when a nested value contains nested items). Nested values differ from non-nested values comprised of the same scalars only by the number spaces between the scalars, which is difficult to see if the values are long or deeply nested. For that reason, APL interpreters often come with functions, either built-in or defined functions that display the structure of nested values in a clearer way. In IBM APL2 these functions are called DISPLAY and DISPLAYC (in workspace DISPLAY, the two functions slightly differ in style). In GNU APL the functions are built-in and are several subfunctions of dyadic ⎕CR (e.g. 4 ⎕CR and 8 ⎕CR, also slightly differing in style). In GNU APL, ⎕CR is a collection of more than 40 subfunctions, some of which play the roles of DISPLAY in IBM APL2. For example:
      1 2 'AB' 3 4       ⍝ standard output formatting
 1 2 AB 3 4 
      4 ⎕CR 1 2 'AB' 3 4      ⍝ same value in 4⎕CR style
┏→━━━━━━━━━━━┓
┃1 2 ┏→━┓ 3 4┃
┃    ┃AB┃    ┃
┃    ┗━━┛    ┃
┗ϵ━━━━━━━━━━━┛
      8 ⎕CR 1 2 'AB' 3 4      ⍝ same value in 8⎕CR style
┌→───────────┐
│1 2 ┌→─┐ 3 4│
│    │AB│    │
│    └──┘    │
└ϵ───────────┘
      1 2 (10 11) 3 4         ⍝ standard output formatting
 1 2  10 11  3 4 
      4 ⎕CR 1 2 (10 11) 3 4   ⍝ same value in 4⎕CR style
┏→━━━━━━━━━━━━━━┓
┃1 2 ┏→━━━━┓ 3 4┃
┃    ┃10 11┃    ┃
┃    ┗━━━━━┛    ┃
┗ϵ━━━━━━━━━━━━━━┛
      8 ⎕CR 1 2 (10 11) 3 4   ⍝ same value in 8⎕CR style
┌→──────────────┐
│1 2 ┌→────┐ 3 4│
│    │10 11│    │
│    └─────┘    │
└ϵ──────────────┘
Some users prefer that APL output is always displayed in the format of 8 ⎕CR (or in one of the other styles that ⎕CR provides). This can be achived by a GNU APL command:
      1 2 'AB' 3 4   ⍝ by default: standard output formatting
 1 2 AB 3 4 
      ⍝ display results automatically in 8 ⎕CR format
      ]BOXING 8

   
      1 2 'AB' 3 4
┌→───────────┐
│1 2 ┌→─┐ 3 4│
│    │AB│    │
│    └──┘    │
└ϵ───────────┘
      ⍝ back to the standard format
      ]BOXING OFF

   
      1 2 'AB' 3 4
 1 2 AB 3 4 

   
   

3.1.5 Multi-Line Strings

In APL1 text with several lines would normally be expressed as a two dimensional character matrix:
      3 5⍴"Peter", "Paul ", "Mary "   ⍝ 3-line APL1 text matrix
Peter
Paul 
Mary 
That approach becomes rather cumbersome and inefficient when the number of text rows is large (a single long line would "blow up" the other lines to its length, yielding a larger than necessary matrix that consist mostly of trailing spaces). In the days of APL1 that was sort of acceptable because the focus was more on numerical computations rather than text processing and the rare texts were mostly used as short decorators for the numbers displayed. Things have changed since then and with the advent of nested values in APL2 one would express long texts as a vector of nested strings rather than as character matrices:
      "Peter" "Paul" "Mary"   ⍝ nested 3-item APL2 vector (note the lack of trailing input spaces and the output indentation)
 Peter Paul Mary 
      ⊃ "Peter" "Paul" "Mary"   ⍝ back to APL1 text matrix (not indented)
Peter
Paul 
Mary 
Even though this improves over APL1, it is still cumbersome if the number of lines is large or not known beforehand. In that case one often finds, even in APL2, constructs like:
      TEXT←3⍴0      ⍝ reserve space for 3 (nested) lines

   
      TEXT[1]←⊂'Peter'   ⍝ ⊂ turns text vector 'Peter' into a nested scalar

   
      TEXT[2]←⊂'Paul'

   
      TEXT[3]←⊂'Mary'

   
      ⊃ TEXT
Peter
Paul 
Mary 
Or, even worse (since the execution time increases quadratically with the number of lines):
      TEXT←⍬        ⍝ start with an empty vector

   
      TEXT ← TEXT, ⊂'Peter'   ⍝ append line 'Peter'

   
      TEXT ← TEXT, ⊂'Paul'    ⍝ append line 'Paul' (no trailing space needed)

   
      TEXT ← TEXT, ⊂'Mary'    ⍝ append line 'Mary' (no trailing space needed)

   
      ⊃ TEXT
Peter
Paul 
Mary 
To further improve and simplify the specification of multi-line texts, which is a problem that often occurs in real life APL programs, GNU APL has adopted the concept of multi-line strings from the Python language or from the bash shell. A multi-line string starts and ends with triple quotes and the lines between become a nested text vector:
      TEXT ←  """
→      Peter
→      Paul
→      Mary
→            """
      8 ⎕CR TEXT
┌→────────────────────┐
│┌→────┐ ┌→───┐ ┌→───┐│
││Peter│ │Paul│ │Mary││
│└─────┘ └────┘ └────┘│
└ϵ────────────────────┘
      ⊃ TEXT
Peter
Paul 
Mary 
Note the → prompt (from APL), which indicates that a multi-line string has started but not yet ended. The characters in the triple quotes shall be either " or else (double angle quotes) « in the leading and » in the trailing triple quotes (the same holds, BTW also for normal GNU APL strings. Intelligent editors are able to jump back and forth between matching quotes, but only if the leading quote differs from the trailing quote. Use this capability with care, since it undermines the portability of APL code written for GNU APL.

3.1.6 Summary and Remarks

Constants are used for creating fixed APL values. There are many APL values that cannot be expressed by constants, for example numeric vectors with only one component, or higher-dimensional values like matrices. These values can only be created using functions (as explained further down).

3.2 APL Names

APL knows 3 kinds of names:

3.2.1 User-defined Names

User-defined names start with a letter (A-Z or a-z) or one of the 3 characters _ (underscore), ∆ (delta), or ⍙ (delta-underline. The starting character may be followed by letters, digits, or one of the characters ¯ (overbar), _, ∆, or ⍙. The ∆ and ⍙ characters are often used to separate some common prefix (for example the name of a library) from the functions and variables that are somehow related (for example the functions and variables that belong to a library). User-defined Names are case-sensitive, i.e. Foo and FOO are different names. User-defined names are used to denote APL variables, defined functions, defined operators, or labels in defined functions or operators.

3.2.2 Names of System Functions and System Variables

The names of system functions start with the APL character ⎕ (quad) followed by a small number of letters. System names are case-insensitive, i.e. ⎕IO is the same as ⎕io. Older APL programmers seem to prefer uppercase, presumably because the first APL interpreters had no lowercase characters. Only a handful of system functions and variables are standardized in the ISO standards 8485 and 13751, but every APL interpreter adds many more. Those that are not defined in the standards differ considerably between APL interpreters from different vendors even if their names are the same. Adding non-standard system functions and variables are the normal way of adding features to the APL language; they usually add functions whose implementation in APL would be inefficient or cumbersome.

3.2.3 Names of Primitive APL Functions

The names of primitive functions are single APL characters that differ from all characters allowed in user-defined names. Almost all the primitive APL functions (and hence their names) are identical in all APL interpreters and are standardized in ISO standard 13751. Apart from the differences mentioned above, there is no real difference between system functions and primitive APL functions.

3.3 Functions and Operators

Functions in APL can have none, one, or two arguments. Those with no argument are called niladic, functions with one argument are called monadic, and two-argument functions are called dyadic. Some monadic or dyadic functions can have another, optional, argument used for specifying an axis (a dimension along which the function is computed). In standard APL, only primitive APL functions can have an axis argument, but GNU APL also supports an axis argument for defined functions. Most dyadic functions can also be called with only one argument. These functions are called nomadic. This basically means that the same function name is used for two different functions. The two functions are often related. For example, ÷ is nomadic; its dyadic variant A ÷ B (called divide) divides A by B while its monadic variant (called inverse) divides 1 by B. Another way of putting this is: a nomadic function is a dyadic function whose left argument is optional (and omitting it changes its behavior).

3.3.1 Niladic Functions

A niladic function takes no arguments. A niladic function call is simply the name of the niladic function. For example, ⎕TS is a niladic system function that returns the current time as year, month, day, hours, minutes, seconds, and milliseconds:
      ⎕TS
2024 3 4 15 43 5 933

3.3.2 Monadic Functions

A monadic function takes one argument. A monadic function call consists of the name of the function followed by its sole argument. For example, the monadic variant of the nomadic function ÷ computes the inverse of its argument:
      ÷ 2
0.5
      ÷ 2J2
0.25J¯0.25
If the optional axis argument mentioned above is supported, then it is placed in brackets immediately to the right of the function name.

3.3.3 Dyadic Functions

A dyadic function takes two arguments. A dyadic function call consists of the second (aka. left) argument, followed by the name of the function, followed by its other (aka. right) argument. For example, the dyadic variant of the nomadic function ÷ computes the left argument divided by the right argument:
      4 ÷ 2
2
      4J4 ÷ 2J2
2
As the last example above shows, APL automatically converts numbers to their simplest form, i.e. from complex to real, from floating point to integer, and from integer to Boolean. At least it looks like that. A value that is, for example, printed like an integer may internally still be a real or even a complex number. In older APL interpreters there used to be a function ⎕DR (data representation) that would tell if an APL value was complex, real, integer, or Boolean. For mixed arrays introduced by ISO 13751 that does not make much sense anymore so the ⎕DR function has disappeared.

3.3.4 Monadic Operators

APL operators are functions that have one or two value arguments like monadic or dyadic functions, but in addition take one or two function arguments. The attribute monadic or dyadic of an operator refers to the number of function arguments for the operator and not to the number of value arguments. If OP1 is a monadic operator then (f OP1) is a so-called derived function; depending on the operator its derived function can be monadic or dyadic.

A monadic operator is therefore an operator that has one function argument, and a dyadic operator is an operator that has two function arguments. As far as built-in APL operators are concerned, one of them (the inner/outer matrix product . ) is dyadic and all others are monadic. A monadic operator, together with its function, defines a new function: the derived function. Likewise, a dyadic operator, together with both its functions, defines a derived function of that operator. Derived functions of the same operator but with different function arguments are, of course, different but they are either all monadic functions or all dyadic functions.

We take presumably the most frequently used operator, reduction, as an example. The APL symbol for the reduction operator is / (slash). The function argument of a monadic operator is the function immediately left of the operator symbol. The reduction operator is monadic (taking one function argument), the function provided as its function argument must be dyadic, and the derived function is monadic. The derived function of reduction with function argument f is also called f-reduction.

When the value argument of f-reduction is a vector, then f-reduction computes the result of placing f between the vector elements:

f-reduction v1 v2 ... vn ↔ v1 f v2 f ... vn

If function f is + (addition) then f-reduction of a vector is the sum of its elements:
      +/1 2 3 4 5 6
21
Likewise, if f is ⌈ (maximum) then f-reduction of a vector is the largest of its elements:
      ⌈/2 5 12 4 0
12
The f-reduction of a matrix is a vector with the f-reduction of each row:
      3 3⍴1 2 3 4 5 6 7 8 9
1 2 3
4 5 6
7 8 9
      +/ (3 3⍴1 2 3 4 5 6 7 8 9)
6 15 24
f-reduction is one of the functions that support an axis argument. The axis argument of f-reduction tells along which axis (i.e. rows or columns in the case of a matrix) the f-reduction shall be performed:
      +/[2] (3 3⍴1 2 3 4 5 6 7 8 9)
6 15 24
      +/[1] (3 3⍴1 2 3 4 5 6 7 8 9)
12 15 18
In GNU APL, user defined monadic operators can have an axis argument, which is, like for their built-in pendants, placed in brackets right of the operator symbol.

3.3.5 Dyadic Operators

A dyadic operator is like a monadic operator but has two function arguments instead of one. If OP1 is a dyadic operator then (f OP1 g) is its derived function. Depending on the operator, its derived functions can be monadic or dyadic. For some dyadic operators their "function arguments" may or must be APL values and not functions. The APL symbol for the inner product operator is . (dot). The function arguments of the inner product are placed immediately left and immediately right of the dot. If A and B are matrices, then A +.× B is the normal matrix product:
      A←3 3⍴1 2 3 4 5 6 7 8 9

   
      A
1 2 3
4 5 6
7 8 9
      A +.× A
 30  36  42
 66  81  96
102 126 150
In general, for two matrices A and B and functions f and g, the inner product f.g is a matrix. The element in row i and column j in that matrix is obtained by applying function g to row i of A and column j of B and then to perform f-reduction of the (row i column) vector. Another way of looking at f.g (or at dyadic operators in general) is to consider (.g) as a derived monadic operator and f.g as f/(.g). However, dyadic operators cannot have an axis argument.

3.4 General APL Values

The constants introduced so far were examples of APL values. However, many APL values cannot be written as constants. In this chapter we will introduce APL values in a more formal way and we will show how arbitrary APL values can be constructed. An APL value is defined by two things: a list of scalars that is called the ravel of the value, and another list that is called the shape of the value. The shape determines how the ravel is arranged to produce an APL value. For example, the same ravel 1 2 3 4 5 6 can be arranged (or "shaped") in 5 different ways:

1. as a 6-element vector:
      1 2 3 4 5 6
   
2. as a 1 by 6 matrix:
      1 2 3 4 5 6
   
3. as a 2 by 3 matrix:
      1 2 3
      4 5 6
   
4. as a 3 by 2 matrix:
      1 2
      3 4
      5 6
   
5. as a 6 by 1 matrix:
      1
      2
      3
      4
      5
      6
   

In this example, the shape selects between the 5 possible arrangements of the ravel. The ravel and the shape are not entirely independent. Instead the following relation is satisfied by every APL value:

The product of all shape elements is equal to the number of ravel elements

The number of shape elements, also called the rank of the value, determines how many elements the shape has:

Rank Commonly called
0 Scalar (no shape dimension)
1 Vector (one shape dimension)
2 Matrix (two shape dimensions)
3 Cube (three shape dimensions)
... values with higher ranks (more than 3 shape dimensions)

A value also has a depth which tells the level of nesting. Simple scalars have a depth if 0. All other values have a depth of (1 + the maximum depth of all ravel elements). Unlike the shape, which can be imposed on a value, the depth is a consequence of the rank (scalar or not) and the ravel of the value. APL programming is the art of creating new APL values from other APL values. The starting point is the constants discussed above and the new APL values are created from existing APL values by calling functions with the existing APL values as function arguments. You have probably heard that APL has a large number of built-in functions. As a consequence, the same new APL value can usually be created in many different ways. APL programmers tend to prefer the way that contains the smallest number of function calls, even though that is not always the "cleanest" way. It is not always obvious how to create a particular APL value. Therefore we present a (somewhat awkward) method that always works. This method uses only a handful of built-in APL functions that - no surprise - belong to the most frequently used functions in APL programs.

3.4.1 Reshape and Shape: ⍴

Reshape is a simple, but powerful, function that creates values of arbitrary shapes. The function call A ⍴ B returns a new APL value Z with shape A and a ravel constructed from the ravel of value B as follows. Let len_B be the number of elements in the ravel of B, and let len_Z be the number of elements in the ravel of Z. Note that the shape of B plays no role in the computation of function reshape. Most frequently scalars and vectors are being reshaped. We can now enter the 5 examples above (which are all cases where len_Z = len_B) in APL:
      6 ⍴ 1 2 3 4 5 6
1 2 3 4 5 6
      1 6 ⍴ 1 2 3 4 5 6
1 2 3 4 5 6
      2 3 ⍴ 1 2 3 4 5 6
1 2 3
4 5 6
      3 2 ⍴ 1 2 3 4 5 6
1 2
3 4
5 6
      6 1 ⍴ 1 2 3 4 5 6
1
2
3
4
5
6
An example with len_Z < len_B) is this:
      2 2 ⍴ 1 2 3 4 5 6
1 2
3 4
The most powerful case is len_Z > len_B, in particular when len_B is small:
      10 10 ⍴ 1 2
1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2
Another illustrative example is the creation of a unity matrix. We will later repeat the creation of a unity matrix with other functions. Creating a unity matrix with function reshape is somewhat less "clean" than other methods, but short and effective (and therefore frequently seen in APL code):
      5 5 ⍴ 1 0 0 0 0 0
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
The monadic variant of ⍴ is called Shape and returns the shape of its right argument:
      ⍴ 1 0 0 0 0 0
6
      ⍴ (5 5⍴1 0 0 0 0 0)
5 5
The parentheses in the last example are not required, but were added for clarity. Like in other languages, expressions in parentheses are evaluated first and the result replaces the parentheses and their content. The shape of a scalar is an empty vector. Empty vectors produce an empty APL output:
      ⍴ 5     ⍝ Shape of a numeric scalar (output is an empty vector)

   
      ⍴ ' '   ⍝ Shape of a character scalar (output is an empty vector)

   
      ⍴ ''    ⍝ Shape of an empty vector
0

3.4.2 Catenate and Ravel: , and ⍪

The next important function on the way to arbitrary APL values is "catenate", or dyadic , (comma). The function call A , B appends values A and B. If A and B are scalars or vectors then the result is somewhat obvious:
      1 1 1 , 2 2 2   ⍝ append vector 1 1 1 and vector 2 2 2
1 1 1 2 2 2
      1 1 1 , 'bbb'   ⍝ append vector 1 1 1 and vector 'bbb'
1 1 1 bbb
If A or B is a matrix or a value with even higher rank, then there are different ways to catenate two values. This is where the optional axis comes into play. The axis argument determines along which axis the concatenation shall take place:
      2 2⍴'A'
AA
AA
      2 2⍴'B'
BB
BB
      (2 2⍴'A') ,[1] (2 2⍴'B')
AA
AA
BB
BB
      (2 2⍴'A'),[2] (2 2⍴'B')
AABB
AABB
The axes of a value are the different elements of its shape vector. A scalar has no axes, a vector has one axis, a matrix has two axes, and so on. When an APL value is printed then the last axis of the value is printed horizontally (on the same output line) while the other axes are printed vertically (on different output lines). The default axis for catenate (i.e. the axis used when no axis argument is given) is the last axis. There is a companion function of , (comma) namely ⍪ (comma-bar) that is identical to comma if an axis is provided, but uses the first axis rather than the last axis if not. Therefore the last two examples could have been written without an axis argument like this:
      (2 2⍴'A') ⍪ (2 2⍴'B')
AA
AA
BB
BB
      (2 2⍴'A') , (2 2⍴'B')
AABB
AABB


Note: There are some more function pairs that differ only by their default behavior when no axis argument is given: ⊖ and ⌽, / and ⌿, and \ and ⍀. The variant with - in the symbol takes the first axis by default while the other variant takes the last axis. The monadic variant of , and ⍪ is a monadic function called "ravel" and returns the ravel of the value. While function reshape can be used, among other things, to create values of higher or lower ranks than vectors, function ravel does the opposite: it brings the rank of values with higher or lower ranks down to rank 1. In other words, function ravel converts a value with arbitrary shape to a vector. If a value is a vector already then function ravel returns (a copy of) that vector.

3.4.3 Universal Character Set (monadic ⎕UCS)

Function ⎕UCS is monadic and computes a value with the same shape as its right argument. The right argument must be simple (i.e. not nested) values whose ravel consists of all integers or all characters. Integers are converted to characters with the same Unicode, while characters are converted to an integer with the Unicode of the character. In most cases the characters that you use in strings will be on your keyboard, but function ⎕UCS can be used if they are not. Examples:
      ⎕UCS 'APL ⍴⍪ $¥£€⍧ ÄÖÜäöüß'    ⍝ Unicode → integer conversion
65 80 76 32 9076 9066 32 36 165 163 8364 9063 32 196 214 220 228 246 252 223
      ⎕UCS 65 80 76 32 9076 9066 32 36 165 163 8364 9063 32 196 214 220 228 246 252 223  ⍝ And back to Unicode
APL ⍴⍪ $¥£€⍧ ÄÖÜäöüß

3.4.4 Construction of arbitrary simple values

The functions reshape, catenate, and occasionally ⎕UCS can be combined to construct arbitrary simple (i.e. not nested) values. We assume, of course, that it is known how the value shall look. The algorithm for constructing the new value is then:
  1. construct the shape vector of the new value from smaller items such as integer scalars or vectors. The integer scalars can be constants or other integer vectors computed elsewhere. Concatenate (dyadic ,) the smaller pieces as needed. Put everything in parentheses (in many cases the parentheses are optional and can be removed, but to be on the safe side we leave them in).
  2. construct the ravel of the new value from smaller items such as integer scalars, integer vectors, character scalars and character vectors. Possibly use ⎕UCS to create single charactera or character vectors using their Unicode. Concatenate (dyadic ,) the smaller pieces as needed.
  3. reshape the ravel with the shape vector using dyadic ⍴.
Steps 1 and 2 are independent, so you can do 2 before 1. As an alert reader you will have noticed that you cannot create new scalars because a scalar has a shape vector of length 0, and we have seen earlier that empty integer constants do not exist. In older APL interpreters this was solved by using an empty character vector instead of an empty integer vector:
      '' ⍴ 1 2 3 4 5 6        ⍝ reshape 1 2 3 4 5 6 to a scalar
1
      ⍴ ('' ⍴ 1 2 3 4 5 6)    ⍝ shape of '' ⍴ 1 2 3 4 5 6
   
This worked well and you will find ''⍴ all over the place in older APL programs. In newer APL interpreters, including GNU APL, a constant ⍬ (zilde) was introduced. ⍬ is an empty numeric vector. ⍬⍴ is cleaner than ''⍴ because a shape should always be an integer vector, but the portability of APL programs using ''⍴ is better than that of ⍬⍴.
You may also wonder if vectors can be created with the above algorithm (and remembering that there are not only no integer vector constants of length 0, but also no integer vector constants of length 1). The answer is "yes" because the left argument A of A⍴B can be a vector or a scalar (the scalar is then treated like a 1-element vector). Note also, that when creating arbitrary simple vectors, Step 2 alone suffices in most cases. For simple vectors, steps 1 and 3 are only needed if the ravel constructed in step 2 has the wrong length.

3.4.5 Construction of arbitrary nested values

The depth of a nested value is recursively defined as: The monadic APL function ≡ (called Depth) returns the depth of an APL value.
In the previous chapter we have seen how arbitrary simple values, i.e. values of depth 0 or 1 are constructed. We can now create a value of depth N + 1 recursively: Examples:
      1 2 3          ⍝ three element vector
1 2 3
      ⍴1 2 3         ⍝ how many elements?
3
      ≡1 2 3         ⍝ how deep?
1
      1 (2 3)        ⍝ two (!) element vector with nested second element
 1  2 3 
      ⍴1 (2 3)       ⍝ how many elements?
2
      ≡1 (2 3)       ⍝ how deep?
2
      1 (2 (3 4))    ⍝ two element vector with nested second element
 1   2  3 4  
      ⍴1 (2 (3 4))   ⍝ how many elements?
2
      ≡1 (2 (3 4))   ⍝ how deep?
3
When the APL interpreter prints nested values it prints extra spaces around them. These spaces distinguish nested values from their simple counterparts with the same ravel elements, but makes it rather difficult to understand values with deeper nesting.

3.4.6 Displaying the structure of values

We have seen in the examples above that that some APL values look the same (e.g. numeric scalars and numeric vectors) or very similar (nested values with the same elements in their ravels, like 1 2 3 vs. 1 (2 3) above). For that reason, APL interpreters that support nested values typically come with a function called Display that shows the structure of a value in a clearer way. This function is very useful for analyzing problems that are caused by different values that look similar:
      1 2 3 + 1 2 3      ⍝ add two 3 element vectors
2 4 6
      1 2 3 + 1 (2 3)    ⍝ add 3 element vector and 2 element vector
LENGTH ERROR
      1 2 3+1 (2 3)
      ^    ^
Since the Display function is of such importance, GNU APL has made it a built-in function called dyadic ⎕CR. The monadic ⎕CR (character representation) is a standard function in all APL interpreters that converts APL values and user defined functions into character strings. The left argument of dyadic ⎕CR does the same, but its left argument lets you choose one of several formats. Formats 4 and 8 of ⎕CR select a format that is very similar to the output of the Display function in other interpreters:
      8 ⎕CR 1         ⍝ show structure of scalar 1
1
      8 ⎕CR 1 2 3     ⍝ show structure of simple vector 1 2 3
┌→────┐
│1 2 3│
└─────┘
      8 ⎕CR 1 (2 3)   ⍝ show structure of nested vector 1 (2 3)
┌→──────┐
│1 ┌→──┐│
│  │2 3││
│  └───┘│
└ϵ──────┘
      8 ⎕CR 1 (2 (3 4))   ⍝ show structure of nested vector 1 (2 (3 4))
┌→──────────┐
│1 ┌→──────┐│
│  │2 ┌→──┐││
│  │  │3 4│││
│  │  └───┘││
│  └ϵ──────┘│
└ϵϵ─────────┘
      8 ⎕CR (2 2⍴ 1 2 3 4)    ⍝ show structure of simple matrix 2 2 ⍴ 1 2 3 4
┌→──┐
↓1 2│
│3 4│
└───┘
      8 ⎕CR (2 2⍴ 1 2 3 (2 2⍴4))    ⍝ a nested matrix
┌→──────┐
↓1     2│
│       │
│3 ┌→──┐│
│  ↓4 4││
│  │4 4││
│  └───┘│
└ϵ──────┘
8 ⎕CR is a character matrix constructed according to the following rules:

3.4.7 Vector Notation versus Catenation

For beginners the difference between vector notation (a sequence of items separated by spaces) and catenation (a sequence of items separated by commas) can be confusing because often, in particular for simple scalars and vectors, both of them produce the same result:
      1 2 3
1 2 3
      1,2,3
1 2 3
In the example above, vector notation executes faster because no function needs to be computed. Sometimes, however, vector notation may produce a result other than expected:
      1 2 3 (4 5)
 1 2 3  4 5 
      8 ⎕CR 1 2 3 (4 5)
┌→──────────┐
│1 2 3 ┌→──┐│
│      │4 5││
│      └───┘│
└ϵ──────────┘
      1 2 3,(4 5)
1 2 3 4 5
      8 ⎕CR 1 2 3,(4 5)
┌→────────┐
│1 2 3 4 5│
└─────────┘
Vector notation starts with the leftmost item and adds one item for every space (or group of spaces). If an item added is not a scalar (like (4 5) in the example above) then the item is automatically converted to a nested value. Catenation works differently; in the above example the two vectors 1 2 3 and (4 5) are simply concatenated to form a vector of length 5. The parentheses in (4 5) in in the catenation example were redundant, while the parentheses in the vector notation were not. Once again 8 ⎕CR helped to clarify the matter.

3.4.8 Scalar Extension

Before continuing we need to introduce a fundamental APL mechanism called scalar extension. This mechanism is applied in many places.
Almost all built-in APL functions are partial, which means that there are arguments for which the function returns an error instead of a result. Some of the very few total (i.e. non-partial) functions are monadic ⍴ and monadic ≡. Typically dyadic functions put more requirements on their arguments than monadic functions. The reason is that not only must the individual left and right arguments satisfy some conditions, but the left and right arguments must also fit each other. For example:
      1 2 3 + 1 2 3   ⍝ 1 2 3 is a valid arguments for +
2 4 6
      1 2 + 1 2       ⍝ 1 2 is also a valid arguments for +
2 4
      1 2 + 1 2 3     ⍝ they cannot be mixed, though
LENGTH ERROR
      1 2+1 2 3
      ^  ^
The most common requirement of dyadic functions is that the left and right argument have the same shape. The sum of two 3 element vectors makes sense, while the sum of a 2 element vector and a 3 element vector does not:
      1 2 3 + 4 5 6    ⍝ OK to add two 3 element vectors
5 7 9
      1 2 3 + 4 5      ⍝ not OK to add 2 element vector to 3 element vector
LENGTH ERROR
      1 2 3+4 5
      ^    ^
Now scalar extension is an exception to most matching shape requirements. If one of the arguments of a dyadic function is a scalar, and if the function supports scalar extension, then the scalar argument is automatically reshaped to the shape of the other argument. (If both arguments were scalar, then they have the same shape already and scalar extension would have no noticeable effect).
      1 2 3 + 4      ⍝ OK by virtue of scalar extension of right argument
5 6 7
      1 + 4 5 6      ⍝ OK by virtue of scalar extension of left argument
5 6 7
Scalar extension is applied recursively. If some ravel element of a value A is nested and the corresponding ravel of B is not (or vice versa) then the non-nested element is scalar extended to the other:
      1 2 3 4 + 1 2 3      ⍝ expect length error
LENGTH ERROR
      1 2 3 4+1 2 3
      ^      ^
      1 2 (3 4) + 1 2 3    ⍝ 3 is scalar extended to match (3 4)
 2 4  6 7 

3.4.9 List of Built-in Scalar Functions

The power of APL comes from the large number of built-in functions. Most of them belong to a category called scalar functions and below is a list of them. Normally the monadic and the dyadic variants are closely related and are both scalar functions. An exception is ∼ where the monadic form is a scalar function while the dyadic form is not.

Dyadic: Z←A FUN B FUN Monadic: Z←FUN B
Name/Description Example(s)   Name/Description Example(s)
Plus
Z is A plus B
      2 + 3
5
+ Conjugate
Z is the complex
conjugate of B
      + 1J42
1J¯42
Minus
Z is A minus B
      2 - 3
¯1
- Negative
Z is the negative of B
      - ¯2
2
Times
Z is A times B
      2 × 3
6
× Direction
Z is 1, 0, or ¯1 if B > 0, B = 0, or B < 0 resp.
      × ¯5
¯1
Divide
Z is A divided by B
      3÷2
1.5
÷ Reciprocal
Z is 1 ÷ B
      ÷4
0.25
Minimum
Z is the smaller of A and B
      2 ⌊ 3
2
Floor
Z is B rounded down
      ⌊ 4.7
4
Maximum
Z is the larger of A and B
      2 ⌈ 3
3
Ceiling
Z is B rounded up
      ⌈ 4.7
5
Power
Z is A raised to
the Bth power
      2⋆3
8
Exponential
Z is e to
the Bth power
      ⋆1
2.718281828
Logarithm
Z is the logarithm
of B to base A
      2⍟8
3
Natural Logarithm
Z is the natural
logarithm of B
      ⍟8
2.079441542
Residue
Z is B modulo A
      10∣13
3
Magnitude
Z is the magnitude of B
      ∣3J4
5
Binomial
Z is Γ(1+B) ÷ (Γ(1+A) × Γ(1+B-A))

For integers A≥0 and B≥0:
Z is (B!) ÷ ((A!) × (B-A)!)
      3!5   ⍝ aka. 5 over 3
10
! Factorial
Z is Γ(1+B), aka.
B! for integers B≥0
      !4   ⍝ factorial of B
24
Circular Functions
Z is a function, selected
by integer A, and called
with argument B:

A=¯12: exp(iB)
A=¯11: iB
A=¯10: +B
A=¯9: B
A=¯8: sqrt(B2 - 1)
A=¯7: atanh(B)
A=¯6: acosh(B)
A=¯5: asinh(B)
A=¯4: (B+1) × sqrt((B-1)÷(B+1)))
A=¯3: atan(B)
A=¯2: acos(B)
A=¯1: asin(B)
A=0: sqrt(1 - B2)
A=1: sin(B)
A=2: cos(B)
A=3: tan(B)
A=4: sqrt(1 + B2)
A=5: sinh(B)
A=6: cosh(B)
A=7: tanh(B)
A=8: sqrt(¯1 - B2)
A=9: real(B)
A=10: ∣ B
A=11: imag(B)
A=12: arc(B)
      A,⍪(A←¯13+⍳25) ○ 1.1
¯12 0.4535961214J0.8912073601
¯11            0J1.1
¯10          1.1
 ¯9          1.1
 ¯8            0J1.486606875
 ¯7  1.522261219J¯1.570796327
 ¯6 0.4435682544
 ¯5 0.9503469298
 ¯4 0.4582575695
 ¯3 0.8329812667
 ¯2            0J¯0.4435682544
 ¯1  1.570796327J¯0.4435682544
  0            0J0.4582575695
  1 0.8912073601
  2 0.4535961214
  3  1.964759657
  4  1.486606875
  5   1.33564747
  6  1.668518554
  7 0.8004990218
  8            0J¯1.486606875
  9          1.1
 10          1.1
 11            0
 12            0
Pi Times
Z is Pi times B
      ○1
3.141592654
      ○2
6.283185307
Without
Z is the elements of A
that are not in B
      1 2 3 4 5 6 ∼ 3 4
1 2 5 6
Not
Z is the boolean
complement of B
      ∼ 1 0 1 1 0 0
0 1 0 0 1 1
And/LCM
For boolean A and B is Z the
logical AND of A and B.

For integer A or B is Z the
least common multiple of A and B
      0 0 1 1 ∧ 0 1 0 1
0 0 0 1
N/A
      ∧ 0 1 0 1
VALENCE ERROR
      ∧0 1 0 1
      ^
Or/GCD
For boolean A and B is Z the
logical OR of A and B

For integer A and B is Z the
gratest common divisor of A and B
      0 0 1 1 ∨ 0 1 0 1
0 1 1 1
N/A
      ∨ 0 1 0 1
VALENCE ERROR
      ∨0 1 0 1
      ^
Nand
Z is ∼ (A ∧ B)
      0 0 1 1 ⍲ 0 1 0 1
1 1 1 0
N/A
      ⍲ 0 1 0 1
VALENCE ERROR
      ⍲0 1 0 1
      ^
Nor
Z is ∼ (A ∨ B)
      0 0 1 1 ⍱ 0 1 0 1
1 0 0 0
N/A
      ⍱ 0 1 0 1
VALENCE ERROR
      ⍱0 1 0 1
      ^
Equal
Z is 1 for equal A and B,
and 0 otherwise.
      1 2 3 = 2
0 1 0
= N/A
      = 0 1 0 1
VALENCE ERROR
      =0 1 0 1
      ^
Less Than
Z is 1 if A is less than B,
and 0 otherwise.
      1 2 3 < 2
1 0 0
< N/A
      < 0 1 0 1
VALENCE ERROR
      <0 1 0 1
      ^
Less or Equal
Z is 1 if A s less than or
equal to B, and 0 otherwise
      1 2 3 ≤ 2
1 1 0
N/A
      ≤ 0 1 0 1
VALENCE ERROR
      ≤0 1 0 1
      ^
Not Equal
Z is 1 if A differs from B,
and 0 otherwise
      1 2 3 ≠ 2
1 0 1
N/A
      ≠ 0 1 0 1
VALENCE ERROR
      ≠0 1 0 1
      ^
Greater or Equal
Z is 1 if A s greater than or
equal to B, and 0 otherwise
      1 2 3 ≥ 2
0 1 1
N/A
      ≥ 0 1 0 1
VALENCE ERROR
      ≥0 1 0 1
      ^
Greater Than
Z is 1 if A is greater than B,
and 0 otherwise
      1 2 3 > 2
0 0 1
> N/A
      > 0 1 0 1
VALENCE ERROR
      >0 1 0 1
      ^

3.4.10 List of Other Built-in Functions

To have all functions listed in one place, we also provide the remaining build-in APL functions here. These functions are either represented by a single APL character, or by a name that starts with ⎕, followed by one or more letters from A-Z ("quad functions"). There is no big difference between quad functions and other built-in functions, except for the name. Often quad functions are used for services of the underlying operating system, such as time information, user accounting, etc. Note that the non-quad functions are all defined by the ISO APL standard (and identical on all APL interpreters), while very few quad-functions are defined by the standard and the other ones differ considerably between different APL interpreters.

Note: The table below uses the concept of APL variables which have not been introduced yet (but will be soon). If you are an APL novice then please ignore the table for the moment and return to it after variables have been introduced.

Dyadic: Z←A FUN B FUN Monadic: Z←FUN B
Name/Description Example(s)   Name/Description Example(s)
Reshape
Z is the ravel of B (possibly shortened or replicated as needed) with shape A
      2 3⍴1 2 3 4 5 6
1 2 3
4 5 6
Shape
Z is the shape of B
      ⍴ (2 3 ⍴ 1 2 3 4 5 6)
2 3
Join
Z is the concatenation of A and B
      A ← 2 3⍴'abcdef' ◊ B ← 2 3⍴1 2 3 4 5 6

A
abc
def
B
1 2 3
4 5 6
A,B
abc 1 2 3
def 4 5 6
,
Ravel
,B is the ravel of B (a vector with the same elements as B.

Table
⍪B is a 2-dimensional matrix with the elements of B.)
      ⎕ ← B ← 2 3 ⍴ 1 2 3 4 5 6
1 2 3
4 5 6
      ,B
1 2 3 4 5 6
      ⎕ ← B ← 1 2 3 4 5
1 2 3 4 5
      ⍪B
1
2
3
4
5
Index of
Z is the positions of B's elements in A
      'abcdefgh' ⍳ 'hello'
8 5 9 9 9
Index Generator
Z is 1 2 ... B
      ⍳6
1 2 3 4 5 6
Identical
Z is 1 if A and B have the same shape and the same ravel elements (including identical nested ravel elements), and 0 otherwise.
      1 2 3 ≡ 1 2 3   ⍝ same shapes and ravels
1
      1 2 3 = 1 2 5   ⍝ for comparison: equal
1 1 0
      1 2 3 ≡ 1 2 5   ⍝ same shapes, different ravels
0
      1  ≡ ,1   ⍝ same ravel, different shapes
0
Depth
Z is the depth (the level of nesting) of B
      ≡ 1
0
      ≡ 1 2 3
1
      ≡ 1 (2 3) 4
2
Not Identical
Z is 0 if A and B have the same shape and the same ravel elements (including identical nested ravel elements), and 1 otherwise.
      1 2 3 ≢ 1 2 3   ⍝ same shapes and ravels
0
      1 2 3 ≠ 1 2 5   ⍝ for comparison: not equal
0 0 1
      1 2 3 ≢ 1 2 5   ⍝ same shapes, different ravels
1
      1  ≢ ,1   ⍝ same ravel, different shapes
1
Tally
Z is the length of the first axis of B
      ≢ 1
1
      ≢ 2 3⍴1 2 3
2
      ≢ 4 3⍴1 2 3
4
      ≢ 1 (2 3) 4
3
Member of
Z is a Boolean value with the same shape as A. The elements of Z indicate if the corresponding element in A is equal to some element in B.
      (2 3⍴1 2 3 4 5 6) ϵ 4 5 6 7 8
0 0 0
1 1 1
Enlist
Z is the elements of B listed in depth-first order (all nested sub-values of a ravel element come before the next ravel element at the same level).
      ∈ (1 2 3) (4 5) 6
1 2 3 4 5 6
Deal
Z is a subset of ⎕IO ... ⎕IO+B containing A elements chosen at random
      3 ? 10
7 9 4
      3 ? 10
4 2 10
? Roll
Z has the same shape as B. The elements of Z are random numbers between ⎕IO and ⎕IO+b where b is the corresponding element in B.
      ? 10 100 1000
5 95 697
Grade Up/Down with collating sequence
A is a character array which defines a sorting order for characters. B is a character vector (string) to be sorted. Z is an integer vector such that B[Z] is sorted according to the sorting order defined by A.
      ⎕IO←1                         ⍝ ⍋ and ⍒ depend on ⎕IO
   
      ⊢B←5 4⍴'DEADBADECEDEBEADDEE'  ⍝ B: the items to be sorted
DEAD
BADE
CEDE
BEAD
DEED
      'ABCDE' ⍋ B                   ⍝ sort B with A < B < C < D < E
2 4 3 1 5
      B['ABCDE' ⍋ B;]               ⍝ the sorted items
BADE
BEAD
CEDE
DEAD
DEED
      B['CBADE' ⍋ B;]               ⍝ same with C < B < A < D < E
CEDE
BADE
BEAD
DEAD
DEED

Grade Up/Down
Z is a vector of indices such that B[Z] is ordered ascendingly (⍋) or descendingly (⍒). In other words, B[⍋B] is B sorted in ascending order and B[⍒B] is B sorted in descending order.
      ⍋ B←1 7 4 2 6
1 4 3 5 2
      B[⍋B]
1 2 4 6 7
      B[⍒B]
7 6 4 2 1
Representation aka. Encode
Z is numbers in B represented in the number system with radices A. ⍴A determines the number of digits in that representation.
      2 2 2 2 2 2 ⊤ 42   ⍝ 42 in base 2 (aka. binary) with 6 digits
1 0 1 0 1 0
N/A
      ⊤ 42
VALENCE ERROR
      ⊤42
      ^
Base Value aka. Decode
Z is the number corresponding to the digits B in the number system with radices A.
      2 ⊥ 1 0 1 0 1 0   ⍝ binary 1 0 1 0 1 0 in decimal
42
N/A
      ⊥ 42
VALENCE ERROR
      ⊥42
      ^
Union
Z is A , B (with duplicates of A in B removed)
      1 2 2 3 'A' ∪ 3 'B' 'C' 'A'
1 2 2 3 ABC
Unique
Z is B with duplicate elements removed
      ∪ 1 2 3 4 3 5
1 2 3 4 5
Format
Z is B formatted according to A
      ⊢B←3 2ρ1 .468987 2 57.276 3 27963
1     0.468987
2    57.276
3 27963
      ⍝ format by specification: (field size + precision)
      ⍝ precisions < 0 imply exponential format
      4 2 12 ¯5 ⍕ B   ⍝ field sizes 4 and 12, precisions 2 and ¯5
1.00   4.6899E¯1
2.00   5.7276E1 
3.00   2.7963E4 
      ⍝ format by example: (example string A)
      ⊢B←234.67 456.23 987.65 34.23
234.67 456.23 987.65 34.23
      "SUM: $5,555.50" ⍕ +/ B
SUM: $1,712.78
Format
Z is B for strings; otherwise B converted to a character vector or matrix
N/A
      2 ⍎ 42
VALENCE ERROR
      2⍎42
      ^^
Execute
Z is the result of executing string B as APL expression
Take
Z is a rectangular sub-area of B according to A
      ⊢V←⍳7
1 2 3 4 5 6 7
      3↑V
1 2 3
      ¯3↑V
5 6 7
      ⊢B←7 7⍴⍳49
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39 40 41 42
43 44 45 46 47 48 49
      3 3↑B
 1  2  3
 8  9 10
15 16 17
      ¯3 ¯3↑B
33 34 35
40 41 42
47 48 49
First
Z is a Scalar containing first element of B (or the prototype of B if B is empty)
Drop
Z is B rectangular sub-area of B according to A
      ⊢V←⍳7
1 2 3 4 5 6 7
      3↓V
4 5 6 7
      ¯3↓V
1 2 3 4
      ⊢B←7 7⍴⍳49
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39 40 41 42
43 44 45 46 47 48 49
      3 3↓B
25 26 27 28
32 33 34 35
39 40 41 42
46 47 48 49
      ¯3 ¯3↓B
 1  2  3  4
 8  9 10 11
15 16 17 18
22 23 24 25
N/A
      ↓ 1 2 3
VALENCE ERROR
      ↓1 2 3
      ^
Find
Z[i] is 1 if A starts at B[i] in B and 0 if not.
      3 4 ⍷ 1 2 3 4 5
0 0 1 0 0
N/A
      ⋸ 'abc'
VALENCE ERROR
      ⍷'abc'
      ^
Index
Z is B[A]
      2 ⌷ 'Hello'
e
⍝ second character
N/A
      ⌷ 1 2 3
VALENCE ERROR
      ⌷1 2 3
      ^
Right
Z is B.
      'Left' ⊢  'Right'
Right
Identity
Z is B. ⊢B is a shortcut for ⎕←B
Left
Z is A
      'Left' ⊣  'Right'
Left
Hide
Z is B as a committed APL value (and is therefore not automatically displayed). ⊣B is a shortcut for (⍳0)⍴B.
      1 + 3
4
      ⊣ 1 + 3
   
Partition
Z is B, divided into partitions according to A. Two elements B[b] and B[b+1] of B belong to the same partition if A[b] ≥ A[b+1] > 0. Each partition becomes a nested item of Z where B[b] with A[b] = 0 are removed.
      1 1  2 2  3 3 3 3 ⊂ 'ABCDEFGH'   ⍝ 3 partitions
 AB CD EFGH 
      1 1  0 0  3 3 3 3 ⊂ 'ABCDEFGH'   ⍝ 2 partitions
 AB EFGH 
Enclose
Z is B for simple scalars, otherwise a scalar that contains B as a nested value
      B←3 4 ⍴5
   
      8 ⎕CR B
┌→──────┐
↓5 5 5 5│
│5 5 5 5│
│5 5 5 5│
└───────┘
      8 ⎕CR ⊂B
┌─────────┐
│┌→──────┐│
│↓5 5 5 5││
││5 5 5 5││
││5 5 5 5││
│└───────┘│
└ϵ────────┘
Pick
Z is a nested sub-value of B, whose position in B is determined by A. Every item of A corresponds to a nesting level of B.
      8 ⎕CR  S←2 3ρ'AB' 'CD' 'EF' 'GH' 'IJ' 'KL'
┌→─────────────┐
↓┌→─┐ ┌→─┐ ┌→─┐│
││AB│ │CD│ │EF││
│└──┘ └──┘ └──┘│
│┌→─┐ ┌→─┐ ┌→─┐│
││GH│ │IJ│ │KL││
│└──┘ └──┘ └──┘│
└ϵ─────────────┘
      (1 3) 2 ⊃ S   ⍝ (1 3) selects 'EF' from S, 2 selects 'F' from 'EF'
F
      (⊃S[1;3])[2]  ⍝ the same.
F
Disclose
Z is the elements of B, with nested sub-values replaced by arrays padded to the same common size
      8 ⎕CR B←2 2⍴'One' 'Two' 'Three' 'Four'
┌→─────────────┐
↓┌→──┐   ┌→──┐ │
││One│   │Two│ │
│└───┘   └───┘ │
│┌→────┐ ┌→───┐│
││Three│ │Four││
│└─────┘ └────┘│
└ϵ─────────────┘
      8 ⎕CR ⊃ B
┌→────┐
↓One  │
│Two  │
│     │
│Three│
│Four │
└─────┘
Rotate
Z is B rotated according to A
      ⊢B←3 5⍴⍳5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
      1 2 3⌽B       ⍝ rotate along the last axis (columns)
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
      ¯1 ¯2 ¯3⌽B    ⍝ rotate backwards along the last axis (columns)
5 1 2 3 4
4 5 1 2 3
3 4 5 1 2
      ⊢B←3/⍪⍳5
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
      1 2 3⊖B       ⍝ rotate along the first axis (rows)
2 3 4
3 4 5
4 5 1
5 1 2
1 2 3

Reverse
Z is B with the items reversed along the first or last axis resp.
      ⌽1 2 3 4 5
5 4 3 2 1
Transpose (General)
Z is B transposed according to A.
A is a vector of numbers in
1 2 3...⌈/A (or in
0 1 2..., if ⎕IO←0).

Permutations A (of ⍳⍴⍴B) permute the axes of B.

Repeated items in A select diagonals in B and reduce the rank of the result.
      ⊢N234←10 ⊥¨ ⍳2 3 4
111 112 113 114
121 122 123 124
131 132 133 134

211 212 213 214
221 222 223 224
231 232 233 234
      1 3 2⍉N234
111 121 131
112 122 132
113 123 133
114 124 134

211 221 231
212 222 232
213 223 233
214 224 234
      1 1 2⍉N234   ⍝ axis 1 repeated
111 112 113 114
221 222 223 224
Transpose (Reverse Axes)
Z is B transposed so that the order of axes is reversed. Z←⍉B ←→ (⌽⍳⍴B)⍉B
      ⊢N234←10 ⊥¨ ⍳2 3 4
111 112 113 114
121 122 123 124
131 132 133 134

211 212 213 214
221 222 223 224
231 232 233 234
      ⍉ N234
111 211
121 221
131 231

112 212
122 222
132 232

113 213
123 223
133 233

114 214
124 224
134 234
Intersection
Z is the elements of A that are also in B
      1 2 3 4 5 6 ∩ 3 4 5 6 7 8
3 4 5 6
N/A
      ∩ 3 4 5 6 7 8
VALENCE ERROR
      ∩3 4 5 6 7 8
      ^
Compress
Z is the elements of B with B[i] repeated A[i] times
      1 2 3 4 5 / 'ABCDE'
ABBCCCDDDDEEEEE
1 2 3 4 5 / '1A' '2B' '3C' '4D' '5E'
 1A 2B 2B 3C 3C 3C 4D 4D 4D 4D 5E 5E 5E 5E 5E 
/
N/A (note that f/B is an operator that takes one value argument)
      / 'ABCDE'
SYNTAX ERROR
      /'ABCDE'
      ^
Expand
A[i] is 0 or 1; if 1 then Z[i] is B[i⌷+\A] or ↑0⍴B otherwise.
      1 0 1 0 0 1\1 2 3   ⍝ 1 at 1, 2 at 3, and 3 at 6; ↑0⍴B is 0
1 0 2 0 0 3
1 0 1 0 0 1 \ 'ABC' ⍝ A at 1, B at 3, and C at 6; ↑0⍴B is ' '
A B  C
\
N/A (note that f\B is an operator that takes one value argument)
      \ 'ABCDE'
SYNTAX ERROR
      \'ABCDE'
      ^

3.4.11 List of Built-in Monadic APL Operators

A monadic APL operator OP1 takes 2 or 3 arguments in the following order:
Used with 2 Value Arguments A and B: Z←A f OP1 B OP1 Used with 1 Value Argument B: Z←f OP1 B
Name/Description Example(s)   Name/Description Example(s)
Reduce N-wise
Like f/B and f⌿B except that f is applied to groups C1 C2 ... Cn. Each group Cn has A consecutive items of B and starts at position i of the axis along which the N-wise reductions are computed.
      ⊢R←1 2 3 4 5 6
1 2 3 4 5 6
4 +/ R
10 14 18
+/R[1 2 3 4] ⍝ group C₁ ←→ Z[1]
10
+/R[2 3 4 5] ⍝ group C₂ ←→ Z[2]
14
+/R[3 4 5 6] ⍝ group C₃ ←→ Z[3]
18
      ⊢R←2 6⍴⍳12      ⍝ ⍴⍴R > 1
1 2 3  4  5  6
7 8 9 10 11 12
4 +/ R
10 14 18
34 38 42
/
Reduce
Z is computed by applying f repeatedly along the last axis of B, i.e. Z←[;;1] f B[;;2] f ... f B[;;N] (the number of semicolons is ¯1+⍴⍴B and N←¯1↑⍴B). f⌿B is the same except that f is computed along the first axis of B.
      2 3⍴⍳6      ⍝ example argument B
1 2 3
4 5 6
      +/ 2 3⍴⍳6   ⍝ +/ is the sum of row elements
6 15
      +⌿ 2 3⍴⍳6   ⍝ +⌿ is the sum of column elements
5 7 9
N/A
      2 +\ 1 2 3 4
VALENCE ERROR
      2+\1 2 3 4
      ^ ^
\
Scan
Z←f\B or Z←f⍀B is like Z←f/B or Z←f⌿B resp. except that the partial results of the different invocations of function f are not discarded but included in the result Z.
      +\ 1 2 3 4 5   ⍝ 1, 1+2, 1+2+3, 1+2+3+4, 1+2+3+4+5
1 3 6 10 15
Commute
Z is B f A (the arguments A and B are exchanged)
      2 ÷ 1
2
      2 ÷⍨ 1
0.5
Z is B f B (the single argument B is duplicated)
      ×⍨ 1 2 3 4   ⍝ squares
1 4 9 16
Each (dyadic)
Z[i] is A[i] f B[i] (f is called dyadically for all corresponding items of A and B)
      8 ⎕CR  1 2 3 ,10 20 30
┌→─────────────┐
│1 2 3 10 20 30│
└──────────────┘
      8 ⎕CR  1 2 3 ,¨10 20 30
┌→───────────────────┐
│┌→───┐ ┌→───┐ ┌→───┐│
││1 10│ │2 20│ │3 30││
│└────┘ └────┘ └────┘│
└ϵ───────────────────┘
Each (monadic)
Z[i] is f B[i] (f called monadically for every item B[i] of B)
      8 ⎕CR , 1 2 3
┌→────┐
│1 2 3│
└─────┘
      8 ⎕CR ,¨ 1 2 3
┌→──────────┐
│┌→┐ ┌→┐ ┌→┐│
││1│ │2│ │3││
│└─┘ └─┘ └─┘│
└ϵ──────────┘

3.4.12 List of Built-In Dyadic APL Operators

A dyadic APL operator OP2 takes 3 or 4 arguments in the following order:
Used with 2 Value Arguments A and B: Z←A f OP2 g B OP2 Used with 1 Value Argument B: Z←f OP2 g B
Name/Description Example(s)   Name/Description Example(s)
Inner Product
Z[i;j] is f / A[i] g B[j]. Row A[;j] is multiplied with column B[i;] and the resulting vector V is then f-reduced to give the scalar Z[i;j] (enclosed if necessary to yield a scalar).
For simple numeric matrices A and B this is the "matrix multiplication" known from linear algebra.
      ⊢A←2 2⍴1 2 3 4
1 2
3 4
      ⊢B←2 2⍴1 2 3 4
1 2
3 4
      ⊢A +.× B
 7 10
15 22
f.g Monadic f.g throws an error however ⍨ can be used to duplicate B
      +.× 2 2⍴1 2 3 4
VALENCE ERROR
      +.×2 2⍴1 2 3 4
      ^ ^
      +.×⍨ 2 2⍴1 2 3 4
 7 10
15 22
Outer Product
Z[i;j] is A[i] g B[j]. ⍴Z ←→ (⍴A),⍴B)
      B ∘.× B←⍳10
 1  2  3  4  5  6  7  8  9  10
 2  4  6  8 10 12 14 16 18  20
 3  6  9 12 15 18 21 24 27  30
 4  8 12 16 20 24 28 32 36  40
 5 10 15 20 25 30 35 40 45  50
 6 12 18 24 30 36 42 48 54  60
 7 14 21 28 35 42 49 56 63  70
 8 16 24 32 40 48 56 64 72  80
 9 18 27 36 45 54 63 72 81  90
10 20 30 40 50 60 70 80 90 100
∘.g Monadic ∘.f throws an error however ⍨ can be used to duplicate B
      ∘.× ⍳5
VALENCE ERROR
      ∘.×⍳5
      ^  ^
      ∘.×⍨ ⍳5
1  2  3  4  5
2  4  6  8 10
3  6  9 12 15
4  8 12 16 20
5 10 15 20 25
Rank
Z←A f ⍤ y B is function f applied to the rank-a cells of A and the rank-b cells of B (with a and b defined by y, see monadic case).

This dyadic case uses only a and b of y←m a b; the first item m is used in the monadic case.
The intention of this somewhat confusing definition was apparently the use of the same y in the monadic and dyadic cases. However, a two item y←a b (with a ignored in the monadic case) would have been more plausible.
      0 1 2⌽⍤0 1 'ABC'
ABC
BCA
CAB
Rank
Z←f ⍤ y B is function f applied to the rank-m cells of B (where m is defined by y, see below.).

The rank-v cells of a value V, v≤⍴⍴V, is V enclosed along its v lower axes, i.e. ⊂[(-v)↑⍴V] V

Conceptually is y a 3 item integer vector: y ← m a b. Shorter y are expanded:

y←m ←→ y←m m m y←a b ←→ y←b a b

This monadic case uses only the first item m of y, but not a or b.
      y←0 ◊ ⍳⍤y 1 2 3
1 0 0
1 2 0
1 2 3
      ⍝ ISO standard 13751 uses arrays like N233 below,
   ⍝ whose items are unique and reflect their position
   ⍝ in the array That is, e.g. N233[i;j;k] ←→ ijk
   ⍝
   ⎕ ← N233 ← 10 ⊥¨ ⍳2 3 3
111 112 113
121 122 123
131 132 133

211 212 213
221 222 223
231 232 233
      (,⍤2) N233
111 112 113 121 122 123 131 132 133
211 212 213 221 222 223 231 232 233
      ⍳⍤0 1 2 3     ⍝ ambiguous, see below
1 2 3
      (⍳⍤0) 1 2 3   ⍝ y B ←→ (0) (1 2 3)
1 0 0
1 2 0
1 2 3
      (⍳⍤0 1) 2 3   ⍝ y B ←→ (0 1) (2 3)
 1 1  1 2  1 3 
 2 1  2 2  2 3 
      (⍳⍤0 1 2) 3   ⍝ y B ←→ (0 1 2) (3)
1 2 3
Power Operator
Z←A f ⍣ N B (N > 0):
repeat: Z←B←A f B
(repeats N times).

Z←A f ⍣ N B (N < 0):
repeat: Z←B←A f-1 B
(repeats -N times).

Z←A f ⍣ g B
with function g: repeat: Z←B←A f B
until (A f B) g B.
      2 (×⍣ 5) 1   ⍝ 2 × 2 × 2 × 2 × 2 × 1
32
      2 (×⍣ ¯5) 1   ⍝ ((((1 ÷ 2) ÷ 2) ÷ 2) ÷ 2) ÷ 2
0.03125
      2 (-⍣≤)  6.4   ⍝ (2 - 6.4) = ¯4.4 and 4.4 ≤ 6.4
¯4.4
Power Operator
Z←f ⍣ N B (N > 0):
repeat: Z←B←f B
(repeats N times).

Z←f ⍣ N B (N < 0):
repeat: Z←B←f-1 B
(repeats -N times).

Z←f ⍣ g B
with function g: repeat: Z←B←f B
until (f B) g B.
      (-⍣3) 5    ⍝ - - - 5
¯5
      (-⍣¯3) 5   ⍝ --1 is +
5


Notes: The outer product is considered a dyadic operator here (and also in the APL standard), even though it has only one functional argument and not two. If it were a monadic operator then the function argument g would have to appear left of the operator symbol (.) rather than right of it. In a way one can consider the outer product as the inner product with '∘' being the identity function.

The ISO standard defines f⍤y as dyadic operator (with a left (function) argument f and right (numeric) argument y. y is a numeric vector with 1, 2, or 3 elements, which may be ambiguous in certain cases.

3.4.13 Functions and Operators with Axis Argument

As we have seen above, some built-in functions and operators have variants that operate along the first or along the last axis. For example:
      ⊢A←2 3 ⍴'A'
AAA
AAA
      ⊢B←2 3⍴'b'
bbb
bbb
      A,B   ⍝ catenate along last axis
AAAbbb
AAAbbb
      A⍪B   ⍝ catenate along first axis
AAA
AAA
bbb
bbb
For built-in functions and operators the symbol for the variant that works along the first axis is the symbol for the variant that works along the last axis but with a '-' overstrike. These days APL uses a keyboard layout where every APL character can be entered with the help of the Ctrl-key or with the Alt-key, but in the early days of APL the character '⍪' was produced by typing ',' then backspace (which moved the input cursor back over the ',' just typed) and finally '-'. On a standard ASCII terminal this 3 character sequence would have replaced ',' with '-' but on an APL terminal it instead would have combined the ',' and the '-' resulting in the overstrike character '⍪'. Coming back to our axis arguments topic: Those built-in functions that can operate along the first or along the last axis can also operate along any other axis. The desired axis is provided after the function or operator symbol enclosed in brackets:
      ⊢A←2 3 4⍴'A'
AAAA
AAAA
AAAA

AAAA
AAAA
AAAA
      ⊢B←2 3 4⍴'b'
bbbb
bbbb
bbbb

bbbb
bbbb
bbbb
      A,B   ⍝ catenate along last axis
AAAAbbbb
AAAAbbbb
AAAAbbbb

AAAAbbbb
AAAAbbbb
AAAAbbbb
      A⍪B   ⍝ catenate along first axis
AAAA
AAAA
AAAA

AAAA
AAAA
AAAA

bbbb
bbbb
bbbb

bbbb
bbbb
bbbb
      A,[1]B   ⍝ catenate along first axis
AAAA
AAAA
AAAA

AAAA
AAAA
AAAA

bbbb
bbbb
bbbb

bbbb
bbbb
bbbb
      A,[2]B   ⍝ catenate along middle axis
AAAA
AAAA
AAAA
bbbb
bbbb
bbbb

AAAA
AAAA
AAAA
bbbb
bbbb
bbbb
      A,[3]B   ⍝ catenate along last axis
AAAAbbbb
AAAAbbbb
AAAAbbbb

AAAAbbbb
AAAAbbbb
AAAAbbbb

The axis can be given as a numeric literal as above, but also as a variable whose value is a number indicating a valid axis of the arguments.

3.4.14 System Functions

The built-in APL functions that we have introduced so far were represented by a single APL glyph (UCS character). These functions are commonly referred to as "primitive APL functions" (or operators) or simply "APL primitives". There is another group of built-in APL functions called "System Functions" which are used in the same way as primitives. The distinction between APL primitives and system functions is somewhat arbitrary and not only result from a lack of suitable APL glyphs or keyboard keys but allow an arbitrary number to be defined. The few differences between primitives and system functions are:

For a quick tour of GNU APL the details of the GNU APL system functions are far to extensive and we refer the reader to the GNU APL info manual where the GNU APL specific system functions are described in more detail, and to the ISO standard 13751 for more common system functions. Note that some system functions are obsolete these days but maintained only for backward-compatibility with older (i.e. APL1) interpreters.
3.4.14.1 Z ← ⎕AF B : Atomic Function
Monadic, obsolete. In a pure Unicode interpreter like GNU APL ⎕AF B seems to be the same as ⎕UCS B.
3.4.14.2 Z ← A ⎕AT B : Attributes
Dyadic: For a (user-defined) name FOO which designates an existing defined function or variable, the expression A ⎕AT 'FOO' yields a numeric vector with attributes from a category that is defined by A: Note that the name FOO is quoted to make it a character vector. ⎕AT also accepts a character matrix if the attributes of multiple names shall be obtained.
3.4.14.3 Z ← A ⎕CR B : Character Representation
Monadic: For a (user-defined) name FOO which designates an existing defined function or operator, the expression ⎕CR 'FOO' yields the character representation for that name. The character representation of a function is a character matrix with one line for every line (including the header line) of the function or operator.

Dyadic: As a GNU APL specific feature, dyadic A ⎕CR 'FOO' is one of over 40 different conversion functions. The integer scalar A ≥ 0 selects one of these functions. ⎕CR ⍬ and ⎕CR '' display slightly different lists of the functions implemented so far.
3.4.14.4 Z ← ⎕DL B : Delay
Monadic: ⎕DL N pauses the operation of the interpreter for N seconds.
3.4.14.5 Z ← A ⎕DLX B : Donald Knuth's Dancing Links
Dyadic: ⎕DLX implements a powerful backtracking machine known as "Dancing links" or "Algorithm X". The algorithm was published by Donald Knuth in 2000 and is the algorithm of choice for a class of problems that is best soved by means of backtracking. For example the 8 tower and 8 queens problem on a chess-board or sudokus. Formally ⎕DLX solves the so-called "exact cover problem": given a binary matrix B, find a subset Z of ⍳↑⍴B so that (+/[1]B[Z;]) ≡ ((¯1↑⍴B)⍴1). Less formally: find a sub-matrix S←B[Z;] of B so that every column of S contains exactly one 1. The left argument A of A ⎕DLX B controls the type of result desired such as compute only one solution, compute all solutions, etc.
3.4.14.6 Z ← A ⎕EA B : Execute Alternate
Dyadic: A ⎕EA B computes ⍎B and, if that fails, computes ⍎A. A and B are character vectors containing APL expressions. The result of A ⎕EA B is the result of ⍎A if it succeeds, otherwise the result of ⍎B. If ⍎B succeeds then ⍎A is not computed so that either ⍎B or ⍎A is being computed.
3.4.14.7 Z ← A ⎕EB B : Execute Both
Dyadic: A ⎕EB B computes ⍎B and then ⍎A. Errors in ⍎B are ignored, so that ⍎B and ⍎A are both computed. Typically ⍎A is an error handler for the case where ⍎B has failed, e.g. for providing a replacement for the missing result of ⍎A. ⎕EB is a GNU APL specific feature.
3.4.14.8 Z ← ⎕EC B : Execute Controlled
Monadic: ⎕EC B computes ⍎B but does not interupt the APL interpreter when an error occurs. Instead the 3-element result vector (Z1 Z2 Z3)←⎕EC B indicates the type of result: Z2 is the result that ⎕ET (see below) would have had if ⍎B were computed without ⎕EC. When computed with ⎕EC then ⎕ET is not affected. Z3 is the actual result of ⍎B:
3.4.14.9 Z ← ⎕ENV B : ENvironment Variables
Monadic: GNU APL feature: return the names and values of the environment variables in the operating system at the point in time when the GNU APL interpreter was started. The argument B of ⎕ENV B is a prefix for the names of the environment variables that shall be returned.
3.4.14.10 Z ← A ⎕ES B : Event Simulate
Nomadic: Programmatically simulate an error event. For testing error handlers. Monadic ⎕ES B is ⎕EM ⎕ES B or B ⎕ES ⎕ET depending on B being either a character vector (event message) or a 2-item integer vector (event type).
3.4.14.11 Z ← ⎕EX B : EXpunge
Monadic: Argument B of ⎕EX B specifies one or more name(s) of variables, functions, or operators that shall be erased. For each name, the corresponding result item is 1 on success or 0 on error.
3.4.14.12 Z ← A ⎕FFT B : Fast Fourier Transform
Nomadic. Compute the fast fourier transform of real or complex B. The optional argument A controls details such as a window function to be used for the FFT.
3.4.14.13 ⎕FIO[X] B : File I/O functions
Dyadic: Similar to A ⎕CR B above, A ⎕FIO B is a collection of over 60 different (sub-) functions. Dyadic A ⎕FIO B has a mandatory axis argument X which is an integer scalar X ≥ 0 that selects one of these sub-functions. The sub-function ⎕FIO[X] is then monadic, dyadic or nomadic. As a matter of convenience, the functions A ⎕FIO ⍬ and A ⎕FIO "" (i.e. without an axis argument) display lists of the functions implemented by A ⎕FIO[X] B so far in different formats. The functions in ⎕CR are conversion functions which means that they transform one APL value into another APL value. As a consequence each conversion function is monadic and the left argument B is the value that is being converted. In contrast, the functions in ⎕FIO constitue an interface to the underlying operating system and every function in ⎕FIO corresponds to a C function in library libc. This has two consequences:
  1. the corresponding C function in libc has more often than not two or more arguments. For this reason, the function number which selects the individual function is now the numeric axis argument X of A ⎕FIO[X] B.
  2. the now unused left argument A has now become avaiable as another argument for the selected function ⎕FIO[X]. That is, all functions A ⎕CR are monadic while most functions ⎕FIO[X] are dyadic.
In the early days of GNU APL there were only a few functions ⎕FIO[X] and distinguishing different sub-functions by means of function numbers was already common practice (see, for example, ⎕AT above) and was adequate as long as the number of sub-functions was small. Over the years, however, more and more functions were added to ⎕FIO, and the resulting APL code became more and more difficult to read. Therefore at some point in time a second mechanism - function names instead of function numbers - was added. One could now, for example, write ⎕FIO['fopen'] instead of the less intuitive ⎕FIO[3].

A minor flaw of the new function names was that they needed to be quoted. This led to a third syntax variant where the function name became an (unquoted) APL name instead of a (quoted) APL string. This is most likely the final and most elegant syntax for ⎕FIO where one can now write ⎕FIO.fopen instead of ⎕FIO['fopen'] or ⎕FIO[3].
3.4.14.14 Z ← ⎕FX B : FiX
Monadic: B is either a character matrix or a vector of function lines (function header and APL code). ⎕FX B creates a new defined APL function (see the chapter "Defined Functions" below). With monadic ⎕FX one can therefore create new defined APL functions at runtime.

Dyadic: As a GNU APL feature one cannot only create defined functions that consist of lines of APL code, but also defined functions that were written in other computer languages, most commonly in C/C++. These so-called "native" functions are provided in terms of shared libraries that the user must construct beforehand. In A ⎕FX B A is the file name of a shared library file and B the APL name of the function implemented in the shared library.

GNU APL is shipped with a set of templates for creating native functions or operators that are intended as starting points for native functions created by the user.

3.4.14.15 Z ← ⎕GTK B : Gtk GUI
⎕GTK is an interface to GTK (Graphical Tool Kit) version 3. It implements a small subset of the GTK 3 API and is intended for (and limited to) creating simple windows on the screen, for example to request input from the user in a more intuitive way than the old-fsshioned ⎕ and ⍞ input variables.
3.4.14.16 Z ← A ⎕JSON B : JSON parser
Monadic: B is a text string in JSON (JavaScript Object Notation) format which is converted to the corresponding APL value Z.

Dyadic: B is an APL value which is converted to the corresponding JSON string. A controls some aspect of this conversion, for example to read the JSON data string from a file rather than from an APL text vector.
3.4.14.17 Z ← A ⎕MAP B : MAP (replace) ravel elements
Z is B but with every occurance of ravel A[j;1] replaced with A[j;2]. The same can be achieved with ⎕RE, but ⎕MAP is optimized for this kind of 1:1 replacement while ⎕RE is more powerful but slower.
3.4.14.18 Z ← ⎕INP B : INPut from script
⎕INP is an early attempt to handle multi-line literals in GNU APL. It has been obsoleted by GNU APL multi-line literals but is still used internally. ⎕INP should not be used in ordinary APL programs.
3.4.14.19 Z ← ⎕NA B : Name Association
Obsolete. Throws a "NOT YET IMPLEMENTED" exception when called. This function ony exists so that workspaces from IBM APL2 that use it can be imported into GNU APL.
3.4.14.20 Z ← ⎕NC B : Name Class
B is a matrix of APL names and Z is the current category for every name:
3.4.14.21 Z ← A ⎕NL B : Name List
Z is a matrix of all (user-defined) names where: every name begins with an APL string A and has one of the name classes in numeric vector B.
3.4.14.22 Z ← A ⎕PLOT B : Plot a Value
Monadic: Simple plot (without attributes). The value B is plotted (i.e. displayed in a separate window) with default parameters for colors, line and point sizes, etc.

Dyadic: Simple plot (with attributes). The value B is plotted with user-defined attributes in A.
3.4.14.23 Z ← A ⎕PNG B : Process PNG files and Pixel Images
Monadic: Z ← ⎕PNG B with string B: Convert PNG file B into an array of color planes. monochrome images have one color plane while RGB images have 3 color planes (red, green, and blue). All images may have an additional opacity plane (aka. alpha channel).

Z[;y;x] is the pixel at position (x, y) in the images, x counting from left to right and y from top to bottom.

Z[1;;] is the gray plane for monochrome (grayscale) images and the red plane for RGB or RGBA images.

Z[2;;] is the alpha channel for monochrome (grayscale) images with alpha channel and the green plane for RGB or RGBA images (unless 2 < ↑⍴Z).

Z[3;;] is the blue plane for RGB or RGBA image (unless 3 < ↑⍴Z).

Z[4;;] is the alpha channel RGBA images (unless 4 < ↑⍴Z).

Z ← ⎕PNG B 3-dimensional array as returned above: Display the pixel array B in a window on the screen.

Dyadic: Z ← A ⎕PNG B : Write pixel array B to file named A.
3.4.14.24 Z ← A ⎕RE B : Regular expression
Dyadic: Z is B processed according to regular expression A. ⎕RE is an interface to libpcre (where pcre stands for Perl-compatible regular expression) and the format of A is described in the different man pages shipped with libpcre.
3.4.14.25 Z ← A ⎕RVAL B : Random APL value
APL provides the primitive ? B which returns an array of (pseudo-) random integers. A ⎕RVAL B generalizes this concept by computing (pseudo-) random APL values instead of pseudo-random integers. That means that not only the raw items of Z but also the shape, depth, and types of the random values is chosen at random. Monadic: ⎕RVAL B produces the next random value. Dyadic: A ⎕RVAL B controls the parameters (probablities) for subsequent calls of monadic ⎕RVAL B. The numeric scalar A specifies which parameter shall be specified: The current settings can be obtained by calling A ⎕RVAL B with B a null vector (e.g., 0 ⎕RVAL ⍬).
3.4.14.26 Z ← [A] ⎕SI B : State Indicator
Return components of the State Indicator (see command )SI below) according to B: The optional left argument A is an integer scalar that selects one level of the )SI stack; if omitted then Z contains all levels of the )SI stack.
3.4.14.27 Z ← ⎕SQL[CMD] B : SQL functions
⎕SQL an interface to a SQL database. See info apl for details.
3.4.14.28 Z ← ⎕SVC B : Shared Variable Control
Obsolete. Shared variables are an ancient communication concept from the mainframe era. They are, to some extent, supported by GNU APL for compatibility with IBM APL2. "Normal" APL variables are assigned and referenced by the same APL interpreter instance (i.e. process). In contrast, Shared variables are assigned and referenced by different processes, making each shared variable a communication link between the processes.

In GNU APL the system function ⎕FIO provides communication channels that are simpler to use than shared variables. For that reason, the system functions and variables related to shared variables are not described in detail here. Users who need them (to run ancient workspaces) supposedly know how they work, and users who don't should avoid them.
3.4.14.29 Z ← ⎕SVO B : Shared Variable Offer
Obsolete. See ⎕SVC above.
3.4.14.30 Z ← ⎕SVQ B : Shared Variable Query
Obsolete. See ⎕SVC above.
3.4.14.31 Z ← ⎕SVR B : Shared Variable Retraction
Obsolete. See ⎕SVC above.
3.4.14.32 Z ← ⎕SVS B : Shared Variable State
Obsolete. See ⎕SVC above.
3.4.14.33 Z ← [A] ⎕STOP B : STOP vector
B is a simple string with the name of a defined function.
Z is the stop vector for that defined function.

if A is omitted then the stop vector for defined function B is returned. Otherwise the stop vector for the defined function is set to A. Setting the stop vector creates breakpoints at the lines in A. When such a breakpoint is reached then APL execution stops and a new immediate execution context is entered. The user can then examine and/or change variables, terminate or continue the APL execution with →, execute comands, etc.
3.4.14.34 Z ← A ⎕TF B : Transfer Form
⎕TF converts an object in the current workspace into an APL string (and vice versa).

The integer scalar A selects the format for the result Z; A←1 produces the migration transfer form while A←2 produces the extended transfer form of an object. String B is the name of an object (i.e. a variable, defined function, or (with A←2) a defined operator) in the current workspace. Z is a string which is a text encoding of the object that can be stored in files, transferred over a network, etc. and that can be converted back to an identical object in some other workspace. The migration transfer form can only be used for old APL1 (aka. ISO standard 8485) functions and variables because it does not support APL2 (aka. ISO standard 13751) extensions, in particular not: mixed values, nested values, and defined operators. The format uses fixed size records of 80 bytes each, which makes it compatible with standard 80 column Hollerith punch cards (the now obsolete but previously prevalent storage medium for APL workspaces in the 1960s when APL was invented). For example:
      )CLEAR
CLEAR WS
      ∇Z←A FOO B
      Z←1 2 3
      ∇
      1 ⎕TF 'FOO'   ⍝ the migration transfer form of defined function FOO
FFOO 2 2 9 Z←A FOO BZ←1 2 3  

   
   In contrast, the extended transfer form supports these APL2 extensions. It
   uses strings of APL code (primarily APL literals, ⎕FX for defined functions
   and operators, and ← for variables). For example:
   
   
      )CLEAR
CLEAR WS
      ∇Z←A FOO B
      Z←1 (2 3) 'Hello'   ⍝ nested and mixed
      ∇
      2 ⎕TF 'FOO'   ⍝ the extended transfer form of defined function FOO
⎕FX 'Z←A FOO B' 'Z←1 (2 3) ''Hello''   ⍝ nested and mixed'

   If the string B is the result Z of some prior ⎕TF conversion, then
   A ⎕TF B creates the corresponding object in the current workspace and Z is
   the name of the object created (or '' if an error occurred).
   
   
3.4.14.35 Z ← ⎕XML B : XML parser
⎕XML provides a set of functions for parsing XML documents and to extract the data contained in them. See info apl for details.
3.4.14.36 Z ← ⎕TRACE B : TRACE vector
⎕TRACE is similar to ⎕STOP above. The difference is that ⎕STOP stops the execution when it hits a breakpoint while ⎕TRACE merely generates a printout when it hits a breakpoint.
3.4.14.37 Z ← ⎕UCS B : Universal Char Set
⎕UCS converts APL characters to APL integers (with the codepoint of the character), and vice versa. B can be a mix of characters and the direction of the conversion is determined by the type of the item. Example:
      ⎕UCS 'Hello ', 119 111 114 108 100
72 101 108 108 111 32 world

3.5 Variables

Like most computer languages, APL has variables. Unlike compiled computer languages, variables in APL need not be declared beforehand. Instead, variables are simply created by assigning a value to a name:
      VAR ← 1 2 3
   
If the name is in use for something other than a variable (for instance, a defined function), then a VALUE ERROR will be raised. After a value has been assigned to a name (and, as a side effect of that assignment, a variable with that name has been created) referring to the name returns the most recent value that was assigned to the variable:
      VAR
1 2 3
      VAR ← 1 2 3 4   ⍝ assignment to name VAR

   
      VAR             ⍝ reference of name VAR
1 2 3 4
In the above examples a fundamental APL rule should be explained. Normally a value being computed, for example a constant or the result of a function, is displayed on the screen. If, however, the value is assigned to a variable, then it becomes a committed value which is not displayed. The value is not consumed by the assignment, so that it can be assigned to several variables in one go:
      V1 ← V2 ← 1 2 3

   
      V1
1 2 3
      V2
1 2 3
The lifetime of a variable (though not the lifetime of their value which can change over time) is normally infinite; such variables are called global variables. There exist also local variables whose lifetime begins when a defined function is called and ends when that function call returns a result. This will be explained together with user defined functions). The lifetime of a variable can be explicitly terminated by either the command )ERASE or the APL function ⎕EX (expunge):
      V1
1 2 3
      )ERASE V1

   
      V1
VALUE ERROR
      V1
      ^
      V2
1 2 3
      ⎕EX 'V2'
1
      V2
VALUE ERROR
      V2
      ^
The result 1 of ⎕EX indicates successful erasure of the variable. Note that the argument of ⎕EX is not the variable V2 but a character vector 'V2' containing the name of the variable.

3.5.1 The Variables ⎕ and ⍞

There are two important system variables, ⎕ (quad) and ⍞ (quote quad), that are used because of their side effects. They are probably the most frequently used system variables in APL programs.
3.5.1.1 Input and Output with ⍞
When a value is assigned to ⍞ then the value is displayed on the screen:
      ⍞ ← 1 + 2   ⍝ compute 1 + 2 and display the result
3
In the example above the ⍞ ← is redundant, because the result 3 is not a committed value and would therefore have been displayed anyway. However, ⍞ ← is most useful to display committed values and temporary values inside APL expressions, often for debugging purposes.

When ⍞ is referenced, then a line of input is read from the keyboard (actually from stdin which is normally the keyboard) and the characters read, excluding the end of line character. The result of referencing ⍞ is always a character vector (the user input is quoted by ⍞, which may explain its name quote quad).
      INPUT ← ⍞   ⍝ quote-quad input
what we type

   
      INPUT
what we type
An important special case arises when the assignment of a value to ⍞ (but not ⎕) is immediately (i.e. without another input or output operation) followed by a reference of ⍞. In that case the terminating end-of-line character is suppressed and the input requested on the same line:
      ⍞←"ENTER AMOUNT: " ◊ AMOUNT ← ⍞
ENTER AMOUNT: 42

   
      AMOUNT
              42
This special case is often used in interactive APL programs to print a prompt that tells the user what shall be entered. If this is not desired, then you can use ⎕ instead of ⍞ in the first assignment:
      ⎕←"ENTER AMOUNT: " ◊ AMOUNT ← ⍞
ENTER AMOUNT: 
42

   
      AMOUNT
42
3.5.1.2 Input and Output with ⎕
When a value is assigned to ⎕ then the value is displayed like for ⍞. However, the terminating end of line character is always printed, so that ⎕ cannot display a prompt on the same line as the user input in the way described for ⍞.

Reference to ⎕ differs from referencing ⍞ in two ways:
  1. ⎕ displays its own prompt ⎕: on a separate line, and
  2. evaluates the input line as an APL expression, rather than quoting it automatically like ⍞ does. The evaluation may produce an error if the input entered is not a valid APL expression.
The following examples may help explain the referencing of ⎕.

Example 1: The user references ⎕ and assigns the result to a variable named INPUT:
      INPUT ← ⎕
⎕:
After the ⎕: prompt, the user enters the (valid) APL expression 1 + 2 which evaluates to 3:
      1 + 2
      INPUT
3


Example 2: Like before, the user references ⎕ and assigns the result to a variable named INPUT:
      INPUT ← ⎕
⎕:
After the ⎕: prompt, the user enters the (valid, since quoted) APL string 'Hello' which evaluates to the character vector Hello:
      'Hello'
      INPUT
Hello


Example 3: Like before, the user references ⎕ and assigns the result to a variable named INPUT:
      INPUT ← ⎕
⎕:
After the ⎕: prompt, the user enters the (invalid, since not quoted) Hello. Hello is now an APL name as opposed to an APL string as in example 2. If a variable or niladic function with name Hello were defined, then its value would be assigned to a variable named INPUT. In our example, however, this is not the case and therefore a VALUE ERROR is raised:
      Hello
VALUE ERROR
      Hello
      ^
3.5.1.3 ⎕ Input in Application Programs
Input by means of ⎕ can be very powerful while writing and debugging APL programs. It should be avoided, however, in finished application programs. The reason is that ⎕ throws an error when the user enters something that is not a valid APL expression. In contrast, input by means of ⍞ does not throw errors and is therefore safer to use in application programs.

3.6 Indexing

Most programming languages provide indexing which either references or allows updating a part of the value. Most often, however, indexing is restricted to a single item. In APL, indexing is much more powerful and can even be used to create larger APL values than the indexed value. An index expression, or index, is a sequence of one or more non-negative simple integers. The sequence is enclosed in brackets and the components of the sequence are separated by semicolons (unless there is only one component):
     [1;2 3]

   
   The example above shows an index with 2 components 1 and 2 3. An index cannot
   be used on its own, but is always bound to the value on its left. The value
   left of an index is then said to be indexed by the index expression. The
   semantics of indexing a value is that a subset of the ravel of the value
   is being selected. This subset is then either referenced (copied) or
   changed (assigned) depending on whether the indexed value appears on the
   left of an assignment arrow ← or not. We call a value that is being assigned
   an lvalue (for left value).
   
   The index is most strongly bound to the value on its left, which causes
   indexing of the value to be performed as soon as the value is available.
   If the value is an lvalue (only named lvalues can be assigned) then the
   lvalue is updated with some other value; otherwise the value is referenced.
   
   Often the item left of the index is a variable and then it looks as if parts
   the variable are updated or referenced:
   
   
      V←1 2 3 4   ⍝ create a variable

   
      V[2 3]       ⍝ indexed reference
2 3
      V[2 3]←'x'   ⍝ indexed assignment

   
      V            ⍝ show result of indexed assignment
1 xx 4
What happens behind the scene, however, is that the variable V in the above examples is resolved into a value (indexed reference) or into an lvalue (indexed assignment). The value or lvalue is then being indexed. For indexing to be successful, the index must satisfy certain conditions: As a consequence of the first condition, scalars cannot be indexed (an index without semicolons would require a rank of 1 for the indexed value). The second condition ensures that the corresponding index components do not exceed the corresponding shape components. As a C programmer or mathematician you will find it more natural if the range of an index starts at 0 rather than 1. In APL this can be achieved by setting the system variable ⎕IO (index origin) to 0:
      ⎕IO←0

   
      (1 2 3 4)[2]
3
      ⎕IO←1

   
      (1 2 3 4)[2]
2
Use of ⎕IO←0 should be minimized, however, because most APL programmers assume the default value of 1 for ⎕IO and the readability of your code may suffer. An indexed assignment has the side effect of changing parts of the variable, but the result of it is the value that is assigned, i.e. the right side of the assignment. The result is not displayed. In that respect, indexed assignment behaves like non-indexed assignment.
      V←1 2 3 4

   
      V[3 3 3⍴2]←'X'

   
      V
1 X 3 4
The example above does not make much sense because the same index 2 is assigned 27 times. We used it to show the difference between indexed reference below. An indexed reference of a variable or value has a result whose shape is the concatenated shape of the index. This can be used to create values that are bigger than the indexed value:
      (1 2 3 4)[3 3 3⍴2]
2 2 2
2 2 2
2 2 2

2 2 2
2 2 2
2 2 2

2 2 2
2 2 2
2 2 2
Indexing is one of the essential operations of APL programming and fully understanding it is key to understanding APL. Therefore we summarize the rules governing indexed assignment and indexed reference: A special case of an index item is the "elided index". If no value is given between two brackets or semicolons, then this means that the entire dimension (and not, as you might assume, nothing) is selected by the index item:
      A←3 4 ⍴ 1 2 3 4 5 6 7 8 9 10 11 12

   
      A
1  2  3  4
5  6  7  8
9 10 11 12
      A[2;]   ⍝ elided index for last dimension, i.e. an entire "row"
5 6 7 8
      A[;2]   ⍝ elided index for first dimension, i.e. an entire "column"
2 6 10
A final example shows the effect of multiple items in different dimensions:
      A←6 20⍴'∘'

   
      A
∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘
∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘
∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘
∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘
∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘
∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘∘
      A[;2 3 9 14]←'║'   ⍝ set columns 2, 3, 9, and 14 to ║

   
      A
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
      A[1 3 6;]←'═'   ⍝ set rows 1, 3, and 6

   
      A
════════════════════
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
════════════════════
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
════════════════════
      A[1 3 6;2 3 9 14]←'╬'   ⍝ set rows 1, 3, and 6 in columns 2, 3, 9, and 14

   
      A
═╬╬═════╬════╬══════
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
═╬╬═════╬════╬══════
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
∘║║∘∘∘∘∘║∘∘∘∘║∘∘∘∘∘∘
═╬╬═════╬════╬══════
A disadvantage of APL bracket indexing is that while the shapes of the index items can be freely chosen, the number of semicolons (and therefore the rank of A) is fixed. That makes it impossible to write functions that cope with arbitrary ranks of A. For that reason, a dyadic function X⌷A (called index) is provided where X plays the role of X1;...;XN in bracket index. X is a (typically nested) vector of length N and both reference (Z←X⌷A) and assignment (X⌷A)←B are possible. Unlike bracket index, scalars can be indexed with the index function (X then has length 0), but elided indices are not supported by the index function.

3.7 Execution of APL Statements

APL statements are either entered in immediate execution mode, or else as the body lines of user defined functions. An APL statement starts out as a sequence of characters other than the statement separator ◊ (which, as the name suggests, separates different statements on the same line) and the end of line character (linefeed). The examples provided above were APL statements. An example of a line with 3 statements (and no output) is this:
      A←1 ◊ B←2 ◊ C←3
   
The first thing the APL interpreter does when a statement is entered is to convert the characters of the statement into an internal format called tokens. The translation of a sequence of characters into a sequence of tokens, commonly called lexical analysis or tokenization, can lead to errors when characters are encountered that do not have meaning in APL:
      ∫ f(x) dx
Unknown APL character: ∫ (U+222B)
Non-APL character+

   
   The rules for tokenizing the input characters are relatively simple:
   
   
   
   
   Tokenization is done because operation at the character level is relatively
   inefficient, while the internal token format can be parsed more efficiently.
   In compiled languages tokenization and parsing are both performed by the
   compiler and the efficiency of the internal representation is not relevant
   to the efficiency of the executable program. APL is interpreted, however,
   so part of the parsing is performed at runtime and the purpose of tokenization
   is to perform as much analysis of a statement as possible when the statement
   is entered rather than later (and possibly repeatedly) when the statement
   is executed.
   
   As an example, the statement:
   
   
      VARIABLE←1 2 'Hello' (2 'world')
   
is converted into 3 tokens:



This is possible because the somewhat complicated looking value 1 2 'Hello' (2 'world') is entirely comprized of APL literals which, unless preempted by a higher token binding precedence (see that discussion below), can be collapsed into a single (here nested) value at tokenization time. On the other hand, if there are non-literals (such as functions or names) between the APL literals, then the literals left or right of the non-literals cannot be combined and therefore show up in different tokens:
      VARIABLE←1 2 ⍴ 'Hello' (2 'world')
   



In immediate execution mode, the token sequence created by the tokenization of the input line is immediately executed, and there appears to be no difference between tokenization time and execution time. With user defined functions, however, it pays off to separate lexical analysis from parsing at execution time. The token sequence for the statement is then stored until it is executed. Conceptually, the first step when a statement is executed is to group (also called "bind") certain tokens to other tokens. APL has no operator precedence like other languages (the large number of built-in functions and operators in APL would have made that essentially unmanageable). However, the binding of tokens plays a similar role. Unfortunately the ISO standard fails to mention the rules for token binding, but we can refer to the descriptions of commercial APL vendors. According to those descriptions the binding of tokens has the following precedence (from strongest binding to weakest binding):
  1. bracket index to the token on its left
  2. assignment arrow to the token on its left
  3. dyadic operator to its right operand (the function on its right)
  4. items in vector notation
  5. operator to its left operand (the function on its left)
  6. function to its left argument (the value on its left)
  7. function to its right argument (the value on its right)
  8. assignment arrow to the token on its right
When we refer to, for example, a "token on its left", then this means when the token becomes available. In the following example:
      (2 × 1 2 3 4)[2]
4
the bracket index [2] has the strongest binding. Before that binding can take place, however, the expression in parentheses, (2 × 1 2 3 4), must have been evaluated (yielding 2 4 6 8). The vector 2 4 6 8 is then indexed by bracket index [2] to give the final result 4.

You may also wonder why operators bind to their operand but not to their arguments. The reason is that: Note also that the actual number of binding strengths is smaller than the list above might suggest. This is because some bindings are not in conflict with each other. For example, vector notation binds two or more values to each other, while the next lower binding strength binds an operator to a function. These two bindings could have been given the same binding strength.

Some bindings merely define the order in which things are evaluated while others produce an intermediate result. For example, the binding of a dyadic function to its left argument forces a left argument in parentheses to be evaluated first and then the result to be passed to the dyadic function. On the other hand, the binding of a bracket index to the value or lvalue on its left forces immediate computation of the bracket index as described above.

After binding the token, the evaluation of APL statements is performed according to the "golden rule" of APL:

The rightmost function whose argument(s) are available is evaluated first.
The function and its argument(s) are then replaced by the result returned by the function, which causes the arguments of other functions to become available.


In short this means that APL statements are evaluated from right to left. Another consequence is that parentheses around the right argument of a function have no effect, while parentheses around the left argument make a difference:
      (1 + 2) × (3 + 4)   ⍝ 3 × 7
21
      (1 + 2) × 3 + 4     ⍝ 3 × 7
21
      1 + 2 × (3 + 4)     ⍝ 1 + (2 × 7)
15
      1 + 2 × 3 + 4       ⍝ 1 + (2 × 7)
15

3.8 Defined Functions

Programming in APL is primarily concerned with the creation and testing of user defined functions. The immediate execution mode used so far is helpful to try things out, but not for larger applications.

For the sake of explanation we define a user defined function to be a non-empty sequence of function lines numbered 0, 1, .... The first line is called function header and determines the following properties of the function:

3.8.1 Function Header

The header line of a user defined function consists of several APL names interleaved with some of the characters ←, (, ), [, ], and ;. The names can be freely chosen by the user; we will use the names Z, A, LO, F, X, B, RO, C, and D in our examples with the following meaning: The syntax of the function header is then:

function-header ::= result-spec function-and-args local-variables
result-spec ::= empty | Z ←
function-and-args ::= function-spec | function-spec B | A function-spec B
function-spec ::= function | ( LO function ) | ( LO function RO )
function ::= F | F [ X ]
local-variables ::= empty | ; C local-variables

Additional requirements are that all names in the header must be different and that no name (with the exception of names for local variable names) can be a user defined name. The name of a local variable may be the name of system variables, but must not be the name of a system function or primitive.
The possible combinations in the syntax above produces 2×3×3×2 = 36 different header variants. Of these 36 variants the following 7 combinations are not allowed: The following sections describe the different fields of the function header. Before that we briefly describe one way to create and display user defined functions.
3.8.1.1 Creating and displaying defined functions: ⎕FX and ⎕CR
The monadic system function ⎕FX creates a new function. The single argument of ⎕FX is either a character matrix (the first row of that matrix is the function header) or a vector of nested character vectors (with the first character vector the header of the function). The remaining rows of the matrix or the remaining character vectors are the body lines of the function being created. On success ⎕FX returns the name of the function that it has created. Monadic ⎕CR displays the header and body lines of a function. The single argument of ⎕CR is the name of the function to be displayed. ⎕CR returns a matrix with the function header and the function body.
      )CLEAR
CLEAR WS
      ∇FOO
      1 + 2
      ∇
      ⎕CR 'FOO'
FOO  
1 + 2
3.8.1.2 Result Specification
The example above has created a function FOO that had no result specification. Such functions can be executed, but they do not return a result and attempts to use their return fails:
      )CLEAR
CLEAR WS
      ∇FOO
      1 + 2
      ∇
      FOO                 ⍝ call FOO (that is OK)
3
      VAR←FOO             ⍝ try to use FOO's result (that is an error)
3
VALUE ERROR+
      VAR←FOO
      ^
The reason why some value (3) was displayed is not because FOO has returned the result 3, but because the statement '1 + 2' was not assigned to a variable and therefore printed. For a function to return a result, two conditions must be met:
  1. the header must contain a result specification such as Z←, and
  2. the variable named in the result specification must be assigned during the execution of the function
The result specification is a user-defined name followed by the assignment arrow ← :
      )CLEAR
CLEAR WS
      ⍝ define FOO returning result Z
      ∇Z←FOO
      Z←1 + 2
      ∇
      FOO                         ⍝ call FOO
3
      VAR←FOO                     ⍝ try to use FOO's result

   
      VAR   ⍝ show result
3
The output of simply calling FOO is the same as before. However, the value 3 is now the result of FOO and not the result of the statement Z←1 + 2 inside FOO. This is because the assignment Z←1 + 2 is now a committed value which is not printed. If the function header has a result specification, but the result variable is not assigned, then
      )CLEAR
CLEAR WS
      ⍝ define FOO returning Z without assigning Z (which is more often than not an error)
      ∇Z←FOO
      1 + 2
      ∇
      FOO  ⍝ call FOO
3
      VAR←FOO  ⍝ call FOO (OK) and try to use FOO's result (ERROR)
3
VALUE ERROR+
      VAR←FOO
      ^
Forgetting, as above, to assign the result value inside a defined function whose header indicates that the function returns a result is an error that is sometimes hard to discover, in particular when the function contains branches (so that some execution paths assign the result and some don't). In that case the programmer may be mislead by the fact that the function header indicates a result and incorrectly assumes that the result variable is actually assigned before the function returns.
3.8.1.3 Local Variables
The function header can optionally contain a list of local variables. Every local variable is appended to the function header with a semicolon in front of it. For example:
A FOO B;C;D

   is the header of a dyadic function (with arguments A and B) and local
   variables C and D.
   
   At this point we should reveal that every user defined name, and also the
   APL system variables have an associated stack, The stack is created when
   the name is first mentioned (or from the outset if the name refers to an
   APL system variable).
   
   When a user defined function is called, then the stack of the following
   names is pushed:
   
   
   
   
   After pushing a name, the name refers to nothing, which is usually changed
   shortly after pushing it. The previous values of the name are now
   inaccessible. Only the item on the top of a name's stack can be accessed.
   
   The name on the top of the stack remains accessible until either another
   (or the same) function with the same name in its local variables is called,
   or else until the functions returns. If the function returns then the stacks
   of all its local variable names are popped and the previous top of the stack
   becomes accessible again.
   
   
3.8.1.4 The Del Editor
⎕FX is not the only way to create user defined functions. ⎕FX is good if the function created is small and is often the only way to create new functions programmatically. An alternative present in many APL interpreters is the interactive 'Del' editor. The Del editor is started by entering the APL character Nabla () and the full header of the new function. The Del editor has simple commands for displaying, inserting, editing, and deleting function lines. The Del editor has a prompt which is the next line to be added or changed; This line is displayed in square bracket. If the user wants to change a different line than the line proposed by the Del editor then the desired line is entered (again in square brackets). The following is an overview of Del editor commands:

Command Effect
[N] Continue editing with line N
[⎕] display all function lines
[⎕N] display the function lines 1 to N (inclusive)
[N⎕] display the function line N and those following
[N⎕M] display function lines N to M (inclusive)
[∆N] delete function lines N
[N∆M] delete function lines N to M
[→] discard changes
close the Del editor


Entering a non-existing fractional number, like in [3.5] creates a new line between the closest existing lines (between lines 3 and 4 if there are no other fractional line numbers between 3 and 4). When the Del editor is closed then all lines will be renumbered, starting with header line 0.
These days you will probably use your own editor like Vim or emacs to edit APL functions and then cut-and-paste them into the window in which APL runs, or start APL with a text file containing function definitions. However, at the time when the Del editor was developed, computer mice were not yet invented and terminals were too limited in functionality to support cut-and-paste. Most commands of the Del editor are irrelevant today, but the Del editor is still the method of choice when defining functions in (non-interactive) APL scripts to create new APL functions.
For example, say you have a normal (UTF8 encoded) text file containing the following:
∇ Z←FOO
  1 + 2
∇

   
That defines the same function as;
 ⎕FX 'Z←FOO' '1 + 2'

   
but is more readable, in particular when functions become longer. We will use this format for displaying functions. The above format is also suitable for displaying APL code snippets in emails or on web pages. The reader can simply cut-and-paste them into his interpreter (provided of course, that the interpreter uses UTF8 encoded Unicode and not special APL fonts).
3.8.1.5 Function Body
The remaining lines of a function are called the function body. The function body consists of 0 or more function lines. Every function line consists of 0 or more APL statements like those already discussed above. A function line can have an optional label. A label is another kind of local variable that is automatically created, cannot be changed, and has an integer value that is equal to the number of the line on which it was written. For example:
∇A FOO1 B;C;D
L1: 'line 1'
L2: 'line 2'
 X←L2
∇

   
   The hypothetical function FOO1 above has two arguments A and B, explicit
   local variables C and D, and labels L1 and L2. The syntax for a label is a
   name followed by a colon. The variable X would get the value 2 because
   label L2 is on line 2. labels are read-only; attempting to change their
   value yields a SYNTAX ERROR. Labels will be discussed together with branching
   in functions below.
   
   

3.8.2 How Functions and Operators are Evaluated

The execution (or evaluation) of a function starts when the function name is detected in a statement and all its arguments (as defined by the header of the function) are present. Lets assume we define FOO like this:
      )CLEAR
CLEAR WS
      ⍝ define dyadic FOO with result Z and arguments A and B
      ∇Z←A FOO B;C;D
      L1: 'line 1'
      L2: 'line 2'
      X←L2
      Z←42
      ∇
      ⎕CR 'FOO'   ⍝ check FOO
Z←A FOO B;C;D
L1: 'line 1' 
L2: 'line 2' 
X←L2         
Z←42         

   
   Then we enter the following in immediate execution mode:
   
   
      (3 + 4) FOO 5
line 1
line 2
42
The APL interpreter will see FOO, but it will notice that the left argument of FOO, i.e. (3 + 4,) is not yet available because the result of (3 + 4) has not yet been computed. The interpreter will therefore compute (3 + 4) first and replace it by 7. We have now:
 7 FOO 5

   
   The interpreter can now evaluate 7 FOO 5 (or some other function in the
   general case) as follows:
   
   
  1. first the stacks of all names are pushed. In our example, the names being pushed are Z, A, B, C, D, L1, and L2 (but not FOO!)
  2. next the actual arguments of the function (7 and 5) are assigned to the formal parameters (A and B) of the function. That is, A←7 and B←5.
  3. the labels are assigned, i.e. L1←1 and L2←2.
  4. (at this point, the function result Z and the local variables C and D are undefined, while the function arguments A and B and the labels have values)
  5. the statements in the function body are executed, starting with the first statement in the first line.
  6. the function result Z, which may or may not be defined is stored in a temporary location.
  7. all stacks of all names that were pushed above are popped. They now have the value they had when FOO was called.
  8. the function and its arguments are replaced by the function result in the temporary location.
In our example, the following output is produced:
      (3 + 4) FOO 5
line 1
line 2
42
The first two output lines ("line 1" and "line 2") are output from lines 1 and 2 of FOO, while the last line is the return value from FOO which is displayed after FOO has returned.

3.8.3 Branching

The examples of user defined functions given so far were "linear" by which we mean that the statements in the body of the function were executed one after the other until the end of the function was reached.
In addition to that, APL provides a means to change the order of the normal program flow from the beginning of a function to its end: a computed branch.

APL has been criticized for having only one way of changing the order of the program flow instead of many (like if/else, for, while, and case in C/C++). However the computed branch in APL is so powerful that it can easily emulate the multiple flow control statements in other languages. And the fact that APL works on larger data structures than scalars makes the low-level loops found in other languages obsolete.

A computed branch is a statement that consists of a branch arrow (→) and a numeric APL value. A slightly different statement, called Escape consists of the same branch arrow, but without the value. For example:
3.8.3.1 Labels
The numeric argument of a computed branch is a line number. So →1 is a branch to line 1 of some user defined function. However, absolute line numbers should never be used for branching. The reason is that APL renumbers the lines of a user defined function when new lines are added between existing lines. The line numbers in branches are not renumbered when renumbering lines and as a consequence the absolute line numbers in branches become invalid. This problem can easily be solved by using labels.
A label is an APL name followed by : (colon) at the beginning of a line. The label is an automatically created local variable whose value is the line number on which it was written and the variable is read-only (i.e. one cannot assign a new value to it). Unlike absolute line numbers, labels move with their line when other lines are inserted before them and a subsequent renumbering of lines does them no harm.
Example:

   
∇FOO
    'line 1' ◊ →3    ⍝ Bad: absolute branch to line 3
    'line 2' ◊ →L3   ⍝ Good: branch to line 3 with label L3
L3: 'line 3' ◊ 
∇
If another line is inserted before the first line, then FOO becomes:

   
∇FOO
    'new line before line 1' 
    'line 1' ◊ →3    ⍝ Bad: absolute branch to line 3
    'line 2' ◊ →L3   ⍝ Good: branch to line 3 with label L3
L3: 'line 3' ◊ 
∇
The previous line 3 with label L3 is now line 4. The branch to the absolute line number 3, i.e. →3, now branches to the line before the line with label L3 (which is now most likely wrong), while the branch to label L3 remains correct.
3.8.3.2 Computed Branch (inside a function)
Inside a function a computed branch →EXPR where EXPR is some APL expression is executed as follows. In the following we explain some examples of frequently used branch patterns and their "equivalents" in C/C++

   
                 ⍝ meaning                C/C++

 →0              ⍝ leave the function     return;
 →(COND)⍴0       ⍝ dito if COND           if (COND) return;
 →(COND)↓0       ⍝ dito if not COND       if (!COND) return;

 →LAB            ⍝ goto line LAB          goto LAB;
 →(COND)⍴LAB     ⍝ dito if COND           if (COND)   goto LAB;
 →(COND)↓LAB     ⍝ dito if not COND       if (!COND)  goto LAB;

 →⎕LC            ⍝ repeat current line
 →(COND)⍴⎕LC     ⍝ dito if COND           do { current line } while (COND)

 →⎕LC+1          ⍝ goto next line
 →(COND)⍴⎕LC+1   ⍝ dito if COND           if (COND)     { rest-of-line }

 →⎕LC-1          ⍝ goto previous line
 →(COND)⍴⎕LC-1   ⍝ dito if COND

 →(X=V1,V2 ...)/L1, L2, ...)   ⍝          switch(X) { case V1: goto L1; ... }
In the examples above COND is usually a Boolean expression such as A ≤ B.

Since all APL comparison operators have negated forms (=/≠, ≤/>, </≥, etc.) the (COND)↓ patterns above are far less frequent then the (COND)⍴ patterns. Note also that the (COND)↓ only works for single line numbers (like 0 or LAB above) but NOT for possibly longer vectors like ⎕LC.

The (COND)⍴ pattern also works for non-Boolean integer expressions (like if (COND) with non-integer COND in C/C++). It should not be used, however, if the integer COND is large because then the computation of ⍴ takes a long time and all but the first element of its result is discarded. To avoid that, use 0≠COND instead of COND if COND may be a large integer.
3.8.3.3 Computed Branch (outside a function)
If a computed branch statement is executed outside a function (for example after an error in a function interrupts the execution of the function and returns to immediate execution mode) then the branch is executed as if it were executed inside the interrupted function. An error is thrown if no interrupted function exists.

This can be used to jump back (i.e. continue) the execution of a function that was interrupted (typically after removing the cause of the error).
3.8.3.4 Escape (Unwind)
A single → terminates the execution of the current defined function and removes it from the )SI stack. After that the caller of the current defined function becomes the current defined function.

4 Commands

Every APL interpreter provides a number of commands that can be entered in immediate execution mode. The ISO standard defines a small number of standard commands, and every interpreter adds its own commands for various purposes. Commands do not follow the syntax of the APL language, but are more similar to the input of a shell (a command, followed by mandatory or optional arguments). A command starts with the character ) (or ] for some interpreters) followed by a name.

4.1 Standard Commands

4.1.1 )CLEAR

Syntax: )CLEAR

Re-initializes the current workspace. All user-defined functions and variables are deleted and all system variables are reset to their default values. The workspace name is set to CLEAR WS.

4.1.2 )COPY

Syntax: )COPY [lib] wsname [object ...]

lib is an optional library reference number from 0 to 9. If lib is omitted then it is taken to be 0. The library reference number selects one of 10 directories (which can be configured elsewhere, see command )LIBS below) that contain workspace files.

wsname then selects a workspace file in the directory selected by lib.

Normally the name of the workspace file is either wsname.apl or else wsname.xml. However, if lib is omitted, then the workspace file need not be contained in the directory corresponding to library reference 0, but wsname may instead be an absolute path to the workspace file that shall be copied. This can be useful if the workspace file resides in a non-standard (according to )LIBS) directory, or if both wsname.apl and wsname.xml exist in the same directory.

4.1.3 )COPY_ONCE



Like )COPY, but the workspace file is copied at most once. Subsequent )COPY_ONCE of the same workspace file will be ignored.

4.1.4 )DROP

Syntax: )DROP [lib] wsname

lib is an optional library reference number as for command )COPY above.

wsname selects a workspace in the directory selected by lib. If lib is omitted then an absolute path to the workspace file is accepted as wsname.

Delete the workspace (CAUTION: without any warning).

4.1.5 )ERASE

Syntax: )ERASE symbol ...

The variable, defined function, or defined operator with name symbol is deleted in the current workspace.

4.1.6 )FNS

Syntax: )FNS [from-to]

Display the names of defined functions in the current workspace.

For workspaces with many defined functions, characters from and to can be used as a filter that specifies an alphabetic range of names.

4.1.7 )LIB

Syntax: )LIB [lib|path] [from-to] [sort]

lib is an optional library reference number as for command )COPY above. Alternatively, path may be the absolute path to a non-standard directory that contains workspace files.

from-to is an optional name filter like in )FNS above.

sort is an optional sorting mode, either -size or else -time.

The workspaces in the selected directory are displayed. For directories with many workspace files, characters from and to can be used as a filter that specifies an alphabetic range of names. If no sorting mode is specified then )LIB shows workspaces names (see )WSID below), i.e. without their ,apl or .xml file name extension. Otherwise the file names are displayed with their .apl or .xml extension.

4.1.8 )LOAD

Syntax: )LOAD [lib] wsname

lib is an optional library reference number as for command )COPY above.

wsname selects a workspace in the directory selected by lib. If lib is omitted then an absolute path to the workspace file is accepted as wsname. The current )WSID is updated accordingly.

The current workspace is discarded and the workspace stored in the selected workspace file is made the current workspace.

4.1.9 )NMS

Syntax: )NMS [from-to]

Display the names of variables, defined functions, and defined operators in the current workspace.

For workspaces with many names, characters from and to can be used as a filter that specifies an alphabetic range of names.

4.1.10 )OPS

Syntax: )OPS [from-to]

Display the names of defined operators in the current workspace.

For workspaces with many defined operators, characters from and to can be used as a filter that specifies an alphabetic range of names.

4.1.11 )SAVE

Syntax: )SAVE

Save the current workspace in the file wsname.xml where wsname is defined by the current workspace name (as per )WSID).

Syntax: )SAVE [lib] wsname

lib is an optional library reference number as for command )COPY above.

wsname selects a workspace in the directory selected by lib. If lib is omitted then an absolute path to the workspace file is accepted as wsname and this becomes the new workspace id.

Save the current workspace in the file wsname.xml in the directory selected by lib.

4.1.12 )SI

Syntax: )SI

Every workspace contains a so-called State Indicator similar to the stack-trace of a C program when run in a debugger. Every time a defined function is called a new entry for the defined function is added, and the entry is deleted again when the defined function returns. Due to this last-in-first-out nature the State Indicator is also called the )SI stack.

When the interpreter returns to immediate execution as a result of an error, then the command )SI can be used to display the (recursive) set of defined functions that have been called but not yet finished, and the line number of the current statement in each function.

The )SI command itself displays only the function name and its line number. However there exist several variants of the )SI command that provide additional information for debugging purposes. For example:

      ⍝ clear the SI stack
      )SIC

   
      ⍝ show the SI stack (which is always empty after )SIC)
      )SI

   
      ∇FOO;A;B;C
      1 + 2
      ÷0      ⍝ provoke a DOMAIN ERROR'
      ∇
      FOO
3
DOMAIN ERROR
FOO[2]  ÷0
        ^
      ⍝ show the SI stack again
      )SI
FOO[2]
⋆

   
   In the output of command )SI: an immediate execution entry is displayed
   as * while a defined function is displayed as the function name followed
   by a line number of the function in brackets. In the example above:
   
   
  1. The first line is the )SI entry for the execution of FOO. The execution was stopped in line 2 due to the DOMAIN ERROR, and
  2. The last * is the )SI entry for the immediate execution context in which command )SI was entered. Whenever APL detects an error, it stops execution and created a new )SI entry with mode immediate execution in which the user can then issue commands like )SI and/or change variables, and/or continue execution at the point where the error was detected.

4.1.13 )SIC

Syntax: )SIC

Clear the )SI stack (remove all items and release its resources, particularly localized variables).

4.1.14 )SINL

Syntax: )SINL

)SI with Name List. Same as )SI, but the display of the )SI stack is augmented with the local variables of the function called. In the )SI example:

      )SINL
FOO[2]  A B C
⋆

   
   The first line shows that function FOO was called and has localized the names
   A, B, and C. The second line is an immediate execution context (which cannot
   localize variables). )SINL is useful for determining the scope of a variable
   (e.g. which defined function has last localized it).
   
   

4.1.15 )SIS

Syntax: )SIS

)SI with Statement. Same as )SI, but the display of the )SI stack is augmented with the current statement in the function called (and possibly the error message if the statement had raised an error). In the )SI example:
      )SIS
FOO[2]  ÷0
        ^
⋆  FOO
   ^

   The first line shows the APL statement ÷0 in line 2 of FOO which caused
   the DOMAIN ERROR. The second line shows the statemant FOO that called
   FOO. The order in the display of the )SI stack is therefore from most recent
   to least recent (or downwards from called function to calling function).
   
   
   

4.1.16 )VARS

Syntax: )VARS [from-to]

Display the names of user-defined variables in the current workspace.

For workspaces with many user-defined variables, characters from and to can be used as a filter that specifies an alphabetic range of names.

4.1.17 )WSID

Syntax: )WSID

Display the name of the current workspace.

Syntax: )WSID wsname

Set the name of the current workspace to wsname. The name of the workspace is used, for example, when )DUMP or )SAVE is used and the filename is ommitted.

4.2 IBM APL2 Commands

GNU APL also understands most of the IBM APL2 commands.

4.2.1 )CHECK

Syntax: )CHECK

Perform an internal check of the internal data structures, primarily to detect memory leaks.

4.2.2 )CONTINUE

Syntax: )CONTINUE

Save the current workspace under the name CONTINUE.xml and exit. If APL is started later on and a workspace named CONTINUE exists, then that workspaces is )LOADed automatically. In other words, the APL session is continued at the point where it was left with command )CONTINUE.

4.2.3 )HELP

Syntax: )HELP

Display a list of all GNU APL commands, system variables, and system functions.

Syntax: )HELP primitive

Display a brief help text for the APL primitive primitive.

4.2.4 )HOST

Syntax: )HOST command ...

Execute command command ... in the operating system under which GNU APL runs.

4.2.5 )IN

Syntax: )IN filename [object ...]

Like )LOAD filename [object ...], but for a workspace saved with command )OUT (see below).

4.2.6 )MORE

Syntax: )MORE

APL errors like DOMAIN ERROR, INDEX ERROR etc. are displayed automatically if they occur. For some of these errors, the interpreter has additional information which is, however, not displayed automatically. Command )MORE may display this additional information. Example:
      1 2 3 ⎕MAP 1 2 3
LENGTH ERROR+
      1 2 3 ⎕MAP 1 2 3
      ^     ^
      )MORE
Odd length of A in A ⎕MAP B

   A + character at the end of the APL error indicates that some additional
   information is present and can be displayed with )MORE but it
   must be invoked before anything else is done.
   
   

4.2.7 )OUT

Syntax: )OUT filename [object ...]

Like )SAVE below, but using a different file format. The files have an extension of .atf (for APL Transfer File). Even though the )SAVE command itself is standardized (in the ISO standard), the file format that it produces is not. In contrast, the file format produced by )OUT and understood by )IN is supposed to be understood by different APL interpreters of different vendors, so that workspaces can, at least in principle, be exchanged using )IN and )OUT.

Some vendors have extended the .atf file format, which undermines its primary purpose. GNU APL only supports the original format as described in the IBM APL2 Language Reference Manual.

4.2.8 )OFF

Syntax: )OFF

Exit the APL interpreter with exit code 0.

Syntax: )OFF [exit_code]

Exit the APL interpreter with the given exit code.

4.2.9 )PCOPY

Syntax: )PCOPY [lib] wsname [object ...]

Protective )COPY. Same as )COPY above, but not overwriting existing defined functions and variables.

4.2.10 )PIN

Syntax: )PIN filename [object ...]

Protective )IN. Same as )IN above, but not overwriting existing defined functions and variables.

4.2.11 )RESET

Syntax: )RESET

Same as )CLEAR above.

4.2.12 )SYMBOLS

Syntax: )SYMBOLS [count]

If count is ommitted then display the current number of user-defined names (i.e. for variables, labels, defined functions and defined operators). Otherwise, increase the size of the symbol table to at least count.

4.3 Additional GNU APL Commands

In addition to the commands from the ISO standard and from IBM APL2, GNU APL provides some more commands. These commands are divided into 2 groups: normal commands that start with the character ), and debug commands that start with the character ].

4.3.1 )DUMP

Syntax: )DUMP [[lib] wsname]

Like )SAVE below, but using a different file format. The files have an extension of .apl. The file produced is an APL script which, when executed, reconstructs the current workspace (in terms of variables, defined functions, and defined operators).

The .apl files produced by )DUMP are easier to read (and, if necessary, to modify) than the .xml files produced by )SAVE. On the one hand, .apl files are more portable than .xml files, both in respect to different versions of the GNU APL interpreter and with respect to interpreters from different APL vendors. On the other hand, .apl files have limitations when used with )COPY in libapl.

4.3.2 )DUMP-HTML

Syntax: )DUMP-HTML [[lib] wsname]

lib is an optional library reference number as for command )COPY above.

wsname selects a workspace in the directory selected by lib. If lib is omitted then an absolute path to the workspace file is accepted as wsname.

)DUMP-HTML is similar to )DUMP, but it adds some HTML tagging so that the output file (with file extension .html) can be directly displayed by a web server. This can be useful for sharing your workspaces on the web in such a way that other users can cut-and-paste your code into their GNU APL session.

4.3.3 )HIST

Syntax: )HIST ⍝ show entire history Syntax: )HIST CLEAR ⍝ clear the history Syntax: )HIST filter ⍝ show only history lines starting with filter

)HIST displays previously entered lines. It is sometimes difficult to remember the APL input that has lead to an APL error, and this command may help to reproduce such errors. If called with an argument, then argument CLEAR clears the history, while any other argument is taken as display filter. Only history lines beginning with the given filter are being displayed.

4.3.4 )LIBS

Syntax: )LIBS

Display the current mapping from library reference numbers to directories. For example:
      )LIBS
Library root: /home/eedjsa/apl-1.8

Library reference number to (absolute) path mapping:

╔═══╤═════╤═════════════╤══════════════════════════════════════════════════════╗
║Ref│Conf │State (errno)│ Path to the directory containing the workspace files ║
╟───┼─────┼─────────────┼──────────────────────────────────────────────────────╢
║ 0 │PWD  │ present     │ /home/eedjsa/apl-1.8/workspaces                      ║
║ 1 │PWD  │ present     │ /home/eedjsa/apl-1.8/wslib1                          ║
║ 2 │PWD  │ present     │ /home/eedjsa/apl-1.8/wslib2                          ║
║ 3 │PSYS │ present     │ /usr/local/lib/apl/wslib3                            ║
║ 4 │PSYS │ present     │ /usr/local/lib/apl/wslib4                            ║
║ 5 │PSYS │ present     │ /usr/local/lib/apl/wslib5                            ║
║ 6 │PWD  │ present     │ /home/eedjsa/apl-1.8/wslib6                          ║
║ 7 │PWD  │ missing (2) │ /home/eedjsa/apl-1.8/wslib7                          ║
║ 8 │PWD  │ missing (2) │ /home/eedjsa/apl-1.8/wslib8                          ║
║ 9 │PWD  │ missing (2) │ /home/eedjsa/apl-1.8/wslib9                          ║
╚═══╧══╤══╧═════════════╧══════════════════════════════════════════════════════╝
       │
       ├── NONE:  found no method to compute the library path
       ├── CMD:   the path was set with )LIBS N path
       ├── ENV:   the path came from environment variable $APL_LIB_ROOT
       ├── PSYS:  the path came from the system preferences in file
       │                   /usr/local/etc/gnu-apl.d/preferences
       ├── PUSER: the path came from user preferences in file
       │                   $HOME/.config/gnu-apl or $HOME/.gnu-apl
       └── PWD:   the path is relative to current directory $PWD (last resort)


Syntax: )LIBS [lib] path

lib is an optional library reference number as for command )COPY above.

The directory for library reference number lib is set to path.

4.3.5 )QLOAD

Syntax: )QLOAD [lib] wsname

Quiet )LOAD. Like )LOAD) above, but without printing a SAVED... or DUMPED ... message.

4.3.6 )VALUES

Syntax: )VALUES

Display a (long) list of all APL values (not variables) currently known by the interpreter along with their status (for debug purposes).

4.3.7 ]BOXING

Syntax: ]BOXING [OFF|2|3|4|7|8|9]

Changes the default style of the APL output. Example:
      V←1 (2 3) 'Hello'

   
      ]BOXING OFF

   
      V
 1  2 3  Hello 
      ]BOXING 4

   
      V
┏→━━━━━━━━━━━━━━┓
┃1 ┏→━━┓ ┏→━━━━┓┃
┃  ┃2 3┃ ┃Hello┃┃
┃  ┗━━━┛ ┗━━━━━┛┃
┗ϵ━━━━━━━━━━━━━━┛
      ]BOXING 8

   
      V
┌→──────────────┐
│1 ┌→──┐ ┌→────┐│
│  │2 3│ │Hello││
│  └───┘ └─────┘│
└ϵ──────────────┘
      ]BOXING OFF

   
   

   
   
   

4.3.8 ]COLOR

Syntax: ]COLOR [ON|OFF]

Enables or disables the emission of Escape sequences for colors in the APL output. Output coloring is typically useful in truly interactive mode but requires terminals or terminal windows that support the Escape sequences. There are many situations, however, in which these Escape sequences disturb more than they help, e.g. copy-and-paste between terminal windows, post-processing of APL output.

4.3.9 ]DOXY

Syntax: ]DOXY [path]

Produce a Doxgen-like documentation of the current workspace. If path is omitted then current directory is used as path. Example:
      ⍝ ]DOXY refuses to overwrite existing directories.
      )HOST rm -Rf /tmp/DOXY_TEST
0 
      )WSID DOXY_TEST
WAS CLEAR WS
      ]DOXY /tmp
Command ]DOXY finished successfully.
    The generated documentation was stored in directory /tmp/DOXY_TEST
    You may now browse it from file:///tmp/DOXY_TEST/index.html

   

4.3.10 ]EXPECT

Syntax: ]EXPECT error_count

Accept up to error_count errors before a testcase is considered failed.

4.3.11 ]KEYB

Syntax: ]KEYB

Display an APL Keyboard that can, for example, be used for cut-and-paste of APL characters on keyboards that cannot produce them. For example:
      ]KEYB
US Keyboard Layout:

╔════╦════╦════╦════╦════╦════╦════╦════╦════╦════╦════╦════╦════╦═════════╗
║ ~  ║ !⌶ ║ @⍫ ║ #⍒ ║ $⍋ ║ %⌽ ║ ^⍉ ║ &⊖ ║ *⍟ ║ (⍱ ║ )⍲ ║ _! ║ +⌹ ║         ║
║ `◊ ║ 1¨ ║ 2¯ ║ 3< ║ 4≤ ║ 5= ║ 6≥ ║ 7> ║ 8≠ ║ 9∨ ║ 0∧ ║ -× ║ =÷ ║ BACKSP  ║
╠════╩══╦═╩══╦═╩══╦═╩══╦═╩══╦═╩══╦═╩══╦═╩══╦═╩══╦═╩══╦═╩══╦═╩══╦═╩══╦══════╣
║       ║ Q  ║ W⍹ ║ E⍷ ║ R  ║ T⍨ ║ Y¥ ║ U  ║ I⍸ ║ O⍥ ║ P⍣ ║ {⍞ ║ }⍬ ║  |⊣  ║
║  TAB  ║ q? ║ w⍵ ║ eϵ ║ r⍴ ║ t∼ ║ y↑ ║ u↓ ║ i⍳ ║ o○ ║ p⋆ ║ [← ║ ]→ ║  \⊢  ║
╠═══════╩═╦══╩═╦══╩═╦══╩═╦══╩═╦══╩═╦══╩═╦══╩═╦══╩═╦══╩═╦══╩═╦══╩═╦══╩══════╣
║ (CAPS   ║ A⍶ ║ S  ║ D  ║ F  ║ G  ║ H  ║ J⍤ ║ K  ║ L⌷ ║ :≡ ║ "≢ ║         ║
║  LOCK)  ║ a⍺ ║ s⌈ ║ d⌊ ║ f_ ║ g∇ ║ h∆ ║ j∘ ║ k' ║ l⎕ ║ ;⍎ ║ '⍕ ║ RETURN  ║
╠═════════╩═══╦╩═══╦╩═══╦╩═══╦╩═══╦╩═══╦╩═══╦╩═══╦╩═══╦╩═══╦╩═══╦╩═════════╣
║             ║ Z  ║ Xχ ║ C¢ ║ V  ║ B£ ║ N  ║ M  ║ <⍪ ║ >⍙ ║ ?⍠ ║          ║
║  SHIFT      ║ z⊂ ║ x⊃ ║ c∩ ║ v∪ ║ b⊥ ║ n⊤ ║ m| ║ ,⍝ ║ .⍀ ║ /⌿ ║  SHIFT   ║
╚═════════════╩════╩════╩════╩════╩════╩════╩════╩════╩════╩════╩══════════╝


   The user may change the keyboard that is displayed with ]KEYB, see e.g.
   /usr/local/etc/gnu-apl.d/keyboard1.txt.
   
   

4.3.12 ]LOG

Syntax: ]LOG [facility [ON|OFF]]

Lists or controls GNU APL logging facilities (if configured to do so).

4.3.13 ]NEXTFILE

Syntax: ]NEXTFILE

GNU APL can be started with no, one, or muktiple input files. The ]NEXTFILE command abortes the execution of the current input file and starts the execution of the next file (if any). If there is no next file then it prints an error message and enters immediate execution mode.

4.3.14 ]OWNERS

Syntax: ]OWNERS

Displays some debug information related to all APL values.

4.3.15 ]SVARS

Syntax: ]SVARS

Displays some debug information related to shared variables (an obsolete APL feature that is still supported by GNU APL).

4.3.16 ]SYMBOL

Syntax: ]SYMBOL name

Displays some debug information related to name.

4.3.17 ]USERCMD

GNU APL allows the creation of new APL commands by the user. These commands are implemented as APL code, either as lambdas (for simple commands) or as defined functions (for more complex commands).

Syntax: ]USERCMD

Display all currently defined user commands.

Syntax: ]USERCMD )ucmd APL_fun [mode]

Syntax: ]USERCMD ]ucmd APL_fun [mode]

Define a new user-defined command by means of a defined function. The entire command is passed to the defined function as a string, therefore the function usually needs to drop the name of the command.

It is possible to use the same defined function for different user-defined commands.

Syntax: ]USERCMD )ucmd { ... } Syntax: ]USERCMD ]ucmd { ... }

Define a new user defined command by means of a monadic lambda expression. The entire command is passed to the lambda expression as a string, therefore the lambda expression needs to drop e.g. the name of the command. Example:

First define the command:
      ]USERCMD )sum { +/⍎4↓⍵ }
    User-defined command )sum installed.
Then use the new command:
      )sum 1 2 3
6

Syntax: ]USERCMD REMOVE ]ucmd

Delete the previously defined user command ]ucmd. Example:
      ]USERCMD REMOVE )sum
    User-defined command )sum removed.
Syntax: ]USERCMD REMOVE-ALL

Delete all currently defined user commands.
      ]USERCMD REMOVE-ALL
    All user-defined commands removed.

4.3.18 ]XTERM

Syntax: ]XTERM [ON|OFF]

GNU APL assumes, by default, that it runs interactively in an xterm compatible terminal or terminal emulator such as xterm. In some situations it needs to output Escape sequences, e.g. for positioning the cursor or for clearing lines. In some situations (see command ]COLOR) these Escape sequences are not desired and their emission can be turned off with command XTERM