http://t3x.org/klong/klong-ref.txt.html

Klong Reference Manual

        ================================================================
        |              KLONG  **  A SIMPLE ARRAY LANGUAGE              |
        ================================================================

                               Version 2022-12-12
                                 By Nils M Holm
                              n m h @ t 3 x . o r g

        ----------------------------------------------------------------
        CONTENTS
        ----------------------------------------------------------------

        SYNOPSIS
        LEXEMES
        SYNTAX
        SEMANTICS : VALUES
        SEMANTICS : VERBS
        SEMANTICS : PROJECTION
        SEMANTICS : ARGUMENTS
        SEMANTICS : CONDITIONALS
        SEMANTICS : ADVERBS
        SEMANTICS : ARRAYS
        SEMANTICS : I/O CHANNELS
        SEMANTICS : OPERATORS
        SEMANTICS : FUNCTIONS
        SEMANTICS : VARIABLES
        SEMANTICS : MODULES
        INTERACTION
        INTERACTION : LINE EDITING

        ----------------------------------------------------------------
        SYNOPSIS
        ----------------------------------------------------------------

        Klong is an expression-based language that is inspired by K,
        which is in turn inspired by APL. A Klong program is basically
        a set of functions that manipulate list or array structures.
        You might also think of Klong as a glorified calculator with a
        massive set of functions for transforming arrays in various
        ways.

        One major difference from K is that Klong syntax is unambiguous.
        In K, semantic information is sometimes required to understand
        the syntax of a program, while in Klong, the syntax alone is
        enough to understand the meaning of a program. Of course, the
        ambiguity is by intention in K, because it allows you to write
        very short expressions.

        For instance, the K expression f/x (f over x) may fold "f" over
        "x" or it may find the fixpoint of f(x), depending on the type
        of "f". In its dyadic form, x f/y, "/" may have three different
        meanings: fold, while, and iterate, depending on the type of "x".
        Klong uses different operators in this case: f/x (Over), f:~x
        (Converge), x f:~y (While), and x f:*y (Iterate). Converge and
        While are distinguished by their context (arity).

        Also, Klong does not overload operators to the same degree as
        K does. For instance, in K x_y can denote "drop" or "cut",
        depending on the type of the operand "x". Klong uses :_ for cut
        (and allows integers in the place of "x", e.g.: 3:_y).

        Klong's syntax is similar to K's, so some very simple K programs
        will run in Klong, but the similarity is superficial.

        This is the Klong language reference. If you are not familiar
        with K, J, APL, or a similar language, you might want to read
        the introduction instead.

        ----------------------------------------------------------------
        LEXEMES
        ----------------------------------------------------------------

        Every program is eventually composed of small lexical entities
        (lexemes, tokens) consisting of one or multiple ASCII characters.

        This is an overview of the lexemes that exist in Klong. Basic
        regular expression (regex) syntax (using just the . * + [] \ ?
        operators) is used to describe lexemes. All other characters
        represent themselves.

            . denotes any character
            * denotes zero or more appearances of the previous component
            + denotes one or more appearances of the previous component
            ? indicates that the previous component is optional
        [...] denotes any character contained between the brackets;
              ranges may be abbreviated, e.g. 0-9 for 0123456789
            \ indicates that the following character is a literal
              character and not a regex operator

        :".*"                                                  [Comment]

        A comment. The entire lexeme will be ignored. The regex is in
        fact a lie. See [String], below, for an explanation.
        Examples: :"this is a lie"
                  :"say ""hi"""

        [a-zA-Z\.][a-zA-Z0-9\.]*                                [Symbol]

        A symbolic name, may be used to name variables. Upper and lower
        case is distinguished.
        Examples: foo F00F .d X.

        Note that names starting with "." are reserved for system use.

        [!$%&*+,-\./;<=>?@\\^_|~]                             [Operator]
        :[!$%&*+,-\./;<=>?@\\^_|~]                            [Operator]

        A symbol naming an operator. All operator names are one or two
        characters long. When an operator is two characters long, the
        first character is a colon (:). See also [Shift], below.
        Examples: + @ :^

        Note: there are two non-shifted two-character operators named
        \~ (Scan-Converging) and \* (Scan-Iterating).

        -?[0-9]+                                               [Integer]

        Integer number with optional negative sign. There is no limit on
        the values of integers. Note that the minus sign will only be
        recognized in contexts where a constant is expected (in list and
        dictionaty literals), because in expression contexts, -1 will
        parse as the "-" operator applied to "1".
        Examples: 0 1 -1 1267650600228229401496703205376

        -?[0-9]+\.[0-9]*                                   [Real Number]
        -?[0-9]+e[+-]?[0-9]+                               [Real Number]
        -?[0-9]+\.[0-9]*e[+-]?[0-9]+                       [Real Number]

        Real numbers consist of an integer part plus an optional
        fractional part (after a "." character) and an optional
        exponent part (after an "e" character). Note that the "-"
        prefix will not always be recognized, see [Integers], above.
        Examples: 0.0 0. -1.0 3.1415927 1e6 6.62607004e-34

        Note: 1. is a valid real number, but .1 is not (it is a symbol).

        -?0b[01]+                                       [Binary Integer]
        -?0o[0-7]+                                       [Octal Integer]
        -?0x[0-9a-fA-F]                           [Hexa-Decimal Integer]

        Integer numbers may be specified using an alternative base by
        prepending a 0b (binary), 0o (octal), or 0x (hex) prefix to the
        digits. Upper or lower case letters may be used in hex numbers.
        Examples: 0b101010 0o777 0xcafe 0xDEAD

        0c.                                                  [Character]

        The 0c prefix is used to specify character literals. Unprintable
        characters cannot be specified using 0c. "0c " denotes a blank.
        Examples: 0c0 0ca 0cA 0c* 0c~

        ".*"                                                    [String]

        A string is (almost) any sequence of characters enclosed by
        double quote characters. To include a double quote character in
        a string, it has to be duplicated, so the above regex is not
        entirely correct. A comment is a shifted string (see below).
        Examples: ""
                  "hello, world"
                  "say ""hello""!"

        :lexeme                                                  [Shift]

        The : character is used as a "shift" operator that changes the
        meaning of the following lexeme.

        :operator
        When applied to an operator symbol, it forms a two-character
        operator symbol. E.g.: :^ :$ :=

        :string
        A shifted string is a comment.

        :symbol
        A shifted symbol is being "quoted", i.e. the symbol no longer
        denotes a variable, but a literal symbol name, e.g. :foo, :.d.

        :number, :character
        Shifting other lexemes does not have any effect. The shift sign
        will be ignored in these cases.

        ----------------------------------------------------------------
        SYNTAX
        ----------------------------------------------------------------

        The complete Klong syntax will be given here in EBNF notation.
        An EBNF grammar consists of rules of the form

        a := b c

        meaning "a" can be written as "b c". Rules can be recursive and
        | means "or", so

        x := y | y x

        would mean "'x' can be a 'y' or a 'y' followed by another 'x'",
        which basically means "'x' can be any (positive) number of 'y's".

        y+ is short for the above rule "x" (at least one "y").

        y* is short for (y+|"") where "" means "nothing". Parentheses
        are used for grouping.

        Literal lexemes appear in quotes, e.g.:

        f := '{' p '}'

        meaning "an 'f' is formed by a left brace, followed by a 'p' and
        a right brace".

        NOTE: a newline character translates to a semicolon in Klong,
        except in functions, dictionaries, conditional expressions,
        and lists. So

        a()
        b()

        is equal to a();b(), but

        [1
         2
         3]

        is equal to [1 2 3] and

        :[x;
          y;
          z]

        is equal to :[x;y;z] and

        f::{.d("hello ");
            .p("world!");
            []}

        is a valid function definition.

        Here is the full Klong grammar (an informal description can be
        found at the end of this section):
        ................................................................

        # A program is a ';'-separated sequence of expressions.

        p := e
           | e ';' p

        # An expression is a factor or a dyadic operation applied to
        # a factor and an expression. I.e. dyads associate to the right.

        e := x
           | x d e

        # A factor is a lexeme class (C) or a variable (V) applied to
        # arguments (a) or a function (f) or a function applied to
        # arguments or a monadic operator (m) applied to an expression
        # or a parenthesized expression or a conditional expression (c)
        # or a list (L) or a dictionary (D).

        x := C
           | V a
           | f
           | f a
           | m e
           | '(' e ')'
           | c
           | L
           | D

        # Lexeme classes are the sets of the lexemes specified in the
        # previous section, except for operators.

        C := I   # integer
           | H   # character
           | R   # real number
           | S   # string
           | V   # variable (symbol)
           | Y   # (quoted) symbol

        # A conditional expression has two forms: :[e1;e2;e3] means "if
        # e1 is true, evaluate to e2, else evaluate to e3".
        # :[e1;e2:|e3;e4;e5] is short for :[e1;e2:[e3;e4;e5]], i.e. the
        # ":|" acts as an "else-if" operator. There may be any number of
        # ":|" operators in a conditional.

        c := ':[' ( e ';' e ':|' )* e ';' e ';' e ']'

        # A monadic operator is an operator followed by some optional
        # adverbs or a function or a variable, each followed by at least
        # one adverb.

        m := O A*
           | f A+
           | V A+

        # A dyadic operator is an operator or a function or a variable,
        # each followed by some optional adverbs.

        d := O A*
           | f A*
           | V A*

        # A function is a program delimited by braces. Deja vu? A
        # function may be projected onto on some of its arguments,
        # giving a projection. A variable can also be used to form
        # a projection.

        f := '{' p '}'
           | '{' p '}' P
           | V P

        # Arguments are delimited by parentheses and separated by
        # semicolons. There are up to three arguments.

        a := '(' ')'
           | '(' e ')'
           | '(' e ';' e ')'
           | '(' e ':' e ';' e ')'

        # Projected argument lists are like argument lists (a), but at
        # least one argument must be omitted.

        P := '(' ';' e ')'
           | '(' e ';' ')'
           | '(' ';' e ';' e ')'
           | '(' e ';' ';' e ')'
           | '(' e ';' e ';' ')'
           | '(' ';' ';' e ')'
           | '(' ';' e ';' ')'
           | '(' e ';' ';' ')'

        # A list is any number of class lexemes (or lists) delimited by
        # square brackets.

        L := '[' (C|L)* ']'

        # A dictionary is a sequence of tuples delimited bt ':{' and '}'.

        D := ':{' t* '}'

        # A tuple is a list of two elements.

        t := '[' (C|L) (C|L) ']'

        # The following rules are for compatibility with earlier Klong
        # versions; they allow to use the :() operator instead of () for
        # function application.

        x := V :a
           | f :a

        f := '{' p '}' :P
           | V :P
        ................................................................

        Informally speaking, a Klong program is an expression or
        a sequence of expressions separated by semicolons. Each
        expression is one out of these:

        - a factor (like a string, a function, a number, etc)
        - a prefix monadic verb applied to an expression
        - an infix dyadic verb applied to two expressions,
          associating to the right, so 1-2-3 means 1-(2-3)
        - a function application
        - a conditional expression

        A verb is an operator or a function or a variable (bound to a
        function). They may be followed by on one multiple adverbs.

        ----------------------------------------------------------------
        SEMANTICS : VALUES
        ----------------------------------------------------------------

        Numbers (integer, real), characters, strings, lists, and
        dictionaries all evaluate to their respective values. The
        notation X --> V is used to denote that an expression X
        evaluates to a value V.

            Integer --> Integer
        Real Number --> Real Number
          Character --> Character
             String --> String
               List --> List
         Dictionary --> Dictionary

        All of the above expressions represent constant values, i.e. no
        computation is involved in their evaluation. In particular, all
        members of lists and dictionaries are already in their evaluated
        forms. Lists (and therefore also the tuples in dictionaries)
        auto-quote variables, so

        [Symbol] --> [Symbol]

        Quoted symbols are values, so they also evaluate to themselves.

        :Symbol --> :Symbol

        Variables evaluate to the values that are currently bound to
        them. The :: (define) operator is used to change the value of
        a variable (except for "x", "y", and "z"). See [Define].

        Variable --> value

        Functions are first-class values. They also evaluate to
        themselves:

        Function --> Function

        ----------------------------------------------------------------
        SEMANTICS : VERBS
        ----------------------------------------------------------------

        Operators and functions act as "verbs" in expressions. Both map
        values to values. There are three kinds of operators:

        Monadic operators (or monads) take a single argument and appear
        in prefix positions, like +x, @x, or #x.

        Dyadic operators (or dyads) take two arguments and appear in
        infix positions, like x-y, x*y, x:^y.

        Functions have four different flavors called nilad, monad, dyad,
        and triad, taking 0, 1, 2, and 3 arguments respectively. All
        types of functions expect their arguments in argument lists.
        When a function is bound to a name, the argument list can be
        appended directly to the name:

        f0()
        f1(1)
        f2(1;2)
        f3(1;2;3)

        All verbs return a value that depends on the specific function
        or operator.

        All operators are built into the Klong language, and no new
        operators can be defined by Klong programs. Functions are mostly
        defined by programs, but there are also some pre-defined Klong
        functions. The semantics of operators and pre-defined functions
        will be explained in detail in the sections about OPERATORS and
        FUNCTIONS.

        Functions are programs delimited by curly braces. They return
        the value of the last expression in their programs, e.g. the
        function

        {f();g();h()}

        would return the value of h().

        A named function is defined by assigning an anonymous function
        to a variable, e.g.:

        square::{x*x}

        The type of a function (nilad, monad, dyad, triad) is determined
        by the variables that appear in the function. When a function
        contains the symbol "x", it is a monad, when it contains the
        symbol "y", it is a dyad, and when it contains the symbol "z",
        it is a triad. A function not containing any of these symbols is
        a nilad. E.g.:

        {1}      :"nilad"
        {x}      :"monad"
        {x+y}    :"dyad"
        {x+y*z}  :"triad"

        In function calls, the first argument is assigned to "x", the
        second one to "y", and the third one to "z". It is an error to
        supply more or fewer arguments than a function expects.

        A function containing only the symbol "y" is still a dyad
        (ignoring its first argument), and any function containing "z"
        is still a triad (possibly ignoring some of its arguments):

        {y}   :"dyad"
        {z}   :"triad"
        {x+z} :"triad"
        {y+z} :"triad"

        A function contained in a function does not influence the type
        of the outer function. For example,

        {f({x+y})}

        is a nilad that passes the dyad {x+y} to "f".

        Functions may appear in monads when combined with an adverb:

        {x+y}/[1 2 3]

        or as dyads in expressions:

        1{x+y}2
        f::{x+y}; 1f 2

        Functions may have local variables that are specified in a list
        at the beginning of the function:

        {[variables];program}

        For instance, the function

        {[f];f::x;y@(f'y)?1}

        defines the local variable "f", assigns it the value of the
        argument "x", and then uses it in some computation. See the
        section on "Adverbs and Function Arguments" for an explanation.

        Local variables are bound dynamically: they have an undefined
        value initially and when the function defining them returns,
        they are re-assigned the value they had before the function
        was entered. So

        a::1;{[a];a::2}();a

        will evaluate to 1. Using local variables in escaping functions,
        i.e. in functions returned by functions, is discouraged, because
        their values may change after returning the function.

        ----------------------------------------------------------------
        SEMANTICS : PROJECTION
        ----------------------------------------------------------------

        A projection is a new function that is created by projecting an
        existing function onto at least one of its arguments, resulting
        in the partial application of the original function.

        The notation of projection is that of function application where
        the arguments onto which the function is being projected are
        omitted. For instance,

        Projection   Equivalent function
        {x-y}(5;)    {5-x}
        {x-y}(;5)    {x-5}

        and, given a ternary function f3:

        Projection   Equivalent function
        f3(1;2;)     {f3(1;2;x)}
        f3(1;;3)     {f3(1;x;3)}
        f3(;2;3)     {f3(x;2;3)}
        f3(;;3)      {f3(x;y;3)}
        f3(;2;)      {f3(x;2;y)}
        f3(1;;)      {f3(1;x;y)}

        The projection of a triad is a dyad or a monad, depending on the
        number of arguments onto which the triad is being projected. The
        projection of a dyad is always a monad. There is no projection
        of a monad or nilad.

        Alternatively, monads and nilads can be considered to be their
        own projections (onto zero arguments), but there is no special
        syntax for this case. Any function that is being projected onto
        all of its arguments is simply the function itself.

        Projections are ordinary functions and can be used in all places
        where a verb is expected. For instance:

        f::{x,y}
        f(;0)'[1 2 3]  -->  [[1 0] [2 0] [3 0]]
        f(0;)'[1 2 3]  -->  [[0 1] [0 2] [0 3]]

        g::{x,y,z}
        1g(;2;)3       -->  [1 2 3]

        ----------------------------------------------------------------
        SEMANTICS : ARGUMENTS
        ----------------------------------------------------------------

        There are basically two types of operators in Klong: ones that
        accept compound data types as arguments and those that expect
        atoms exclusively. For instance, the | (reverse) operator
        expects a compound data type, a list, returning a list with the
        original elements in reverse order:

        |[1 2 3]  -->  [3 2 1]

        It is not a type error to pass a non-list to "|" -- in this case
        it will just return its argument (identity). The operation is
        just designed to primarily work on lists.

        Then there are operations that work on atoms exclusively. An
        "atom" is a data object that cannot be decomposed into smaller
        units. Basically all non-list objects are atoms while lists can
        be decomposed into list elements. A string can be viewed as a
        list of characters, so it is also non-atomic. The empty string
        "" and the empty list [] (nil) are atoms.

        For instance, the + (plus) operator is an "atomic operator", i.e.
        it expects atoms as its arguments:

        5+7  -->  12

        However, you can also pass lists to +. There are three cases to
        distinguish: the first element can be a list, the second one,
        or both:

             [1 2 3]+4  -->  [5 6 7]
             1+[2 3 4]  -->  [3 4 5]
        [1 2 3]+[4 5 6] -->  [5 7 9]

        When one operand is a list, the other operand it combined with
        each member of that list. When both operands are lists, their
        elements are combined pairwise.

        Lists can also be written in the form a,b,c instead of [a b c],
        where "," is the "join" operator (see [Join]). The difference to
        bracket notation is that the elements can be dynamic, i.e. you
        can write (a+1),(a+2),a+3 and the values of the list elements
        will be computed at run time.

        Given the Join operator, the above reductions can be written
        like this:

              [a b c]+d  -->  (a+d),(b+d),c+d
              a+[b c d]  -->  (a+b),(a+c),a+d
        [a b c]+[d e f]  -->  (a+d),(b+e),c+f

        This notation is useful, because atomic operators can do even
        more than the above: they can recurse into nested lists. For
        instance,

        [a [b c] d]+e  -->  ((a+e),,((b+e),c+e)),d+e
                            :"[a+e] [[b+e] [c+e]] [d+e]"

        (The monadic "," (List) packages an object in a list, e.g.
         ,1 --> [1], and ,[1] --> [[1]]).

        Even lists of different sizes can be combined, as long as they
        adhere to certain rules:

        [[a b] [c d] [e f]]+[1 2 3]
                           -->  (,((a+1),b+1)),(,((c+2),d+2)),,(e+3),f+3
                                :"[[a+1 b+2] [c+1 d+2] [e+1 f+2]]"

        As long as atoms match atoms, atoms match lists, or lists match
        lists of equal length while descending into the operands, list
        operands of different shapes (see [Shape]) can be combined. For
        example:

        [a b c d]+1                          [a b c d]
                                              1 1 1 1

        [[a b] [c d] [e f]]+[1 2 3]          [[a b] [c d] [e f]]
                                               1 1   2 2   3 3 

        [[[a b] [c d]] [e f]]+[[1 2] 3]      [[[a b] [c d]] [e f]]
                                                1 1   2 2    3 3

        However:

        [a b]+[1 2 3]                        Does not match

        Monadic operators can also be atomic. When an atomic monad is
        applied to a list, the operator is applied to each element of
        the list, recursively, no matter what shape it has:

        -[[1 2 3] [4 5 6]]  -->  [[-1 -2 -3] [-4 -5 -6]]
          -[1 [2 [3] 4] 5]  -->  [-1 [-2 [-3] -4] -5]

        ----------------------------------------------------------------
        SEMANTICS : CONDITIONALS
        ----------------------------------------------------------------

        A conditional expression has the general form :[p;c;a], where "p"
        is the predicate, "c" the consequent, and "a" the alternative of
        the expression. The predicate is being evaluated first. When it
        yields a "true" value, the consequent is evaluated and otherwise
        the alternative is evaluated, so the value of the expression
        depends on the predicate.

        A predicate value is considered to be "false", if it is zero (0),
        nil ([]), or the empty string (""). All other values are treated
        as "true" values. 1 and 0 are the canonical truth values.

        Examples: :[1;:yes;:no]  -->  :yes
                  :[0;:yes;:no]  -->  :no

        Multiple predicate-consequent pairs can be contained in a
        conditional expression by using the :| (Else-If) operator:

        :[p1;c1:|p2;c2:|...:|pN;cN;a]

        In this case, the first consequent (c1) will evaluate only if
        the first predicate (p1) is true, the second consequent (c2)
        will evaluate when then p1 is false but p2 is true, etc. The
        alternative (a) will only evaluate if all predicates are false.

        Formally,

        :[p1;c1:|p2;c2:|...:|pN;cN;a]

        is equal to

        :[p1;c1;:[p2;c2;:[...:[pN;cN;a]...]]]

        Example: ack::{:[0=x;y+1
                       :|0=y;ack(x-1;1)
                       ;ack(x-1;ack(x;y-1))]}

        ----------------------------------------------------------------
        SEMANTICS : ADVERBS
        ----------------------------------------------------------------

        An adverb is an operator that is being attached to a verb,
        thereby modifying the behavior of the verb. In this section,
        "f" denotes a verb (function, operator, or variable bound to
        a function) and "a" and "b" denotes operands. "aI" denotes the
        i'th member of "a", and "aN" denotes its last member.

        f'a                                                       [Each]

        If "a" is a list, apply "f" to each member of "a":

        f'a  -->  f(a1),...,f(aN)

        If "a" is an atom, return f(a). If "a" is [], ignore "f" and
        return [].

        If "a" is a dictionary, apply "f" to each tuple stored in the
        dictionary. The resulting list will be in some random order.
        Applying {x} (the identity function) to a dictionary turns it
        into a list of tuples.

        Example: -'[1 2 3]  -->  [-1 -2 -3]
        ................................................................

        a f'b                                                   [Each-2]

        Each-2 is like each, but applies "f" pairwise to elements of "a"
        and "b":

        a f'b  -->  f(a1;b1),...,f(aN;bN)

        If both "a" and "b" are atoms, return f(a;b). If either "a" or
        "b" is [], ignore "f" and return []. When the lengths of "a" and
        "b" differ, ignore any excess elements of the longer list.

        Example: [1 2 3],'[4 5 6]  -->  [[1 4] [2 5] [3 6]]
        ................................................................

        a f:\b                                               [Each-Left]
        a f:/b                                              [Each-Right]

        If "b" is a list, both of these adverbs combine "a" with each
        element of "b", where :\ uses "a" as the left operand of "f",
        and :/ uses it as its right operand:

        a f:\b  -->  f(a;b1),...,f(a;bN)
        a f:/b  -->  f(b1;a),...,f(bN;a)

        If "b" is an atom, then

        a f:\b  -->  f(a;b)
        a f:/b  -->  f(b;a)

        When "b" is [], ignore "a" and "f" and return [].

        Examples: 1,:\[2 3 4]  -->  [[1 2] [1 3] [1 4]]
                  1,:/[2 3 4]  -->  [[2 1] [3 1] [4 1]]
        ................................................................

        f:'a                                                 [Each-Pair]

        If "a" is a list of more than one element, apply "f" to each
        consecutive pair of "a":

        f:'a  -->  f(a1;a2),f(a2;a3),...,f(aN-1;aN)

        If "a" is an atom or a single-element list, ignore "f" and
        return "a".

        Example: ,:'[1 2 3 4]  -->  [[1 2] [2 3] [3 4]]
        ................................................................

        f/a                                                       [Over]

        If "a" is a list, fold "f" over "a":

        f/a  -->  f(...f(f(a1;a2);a3)...;aN))
        +/a  -->  ((...(a1+a2)+...)+aN)

        If "a" is a single-element list, return the single element.

        If "a" is an atom, ignore "f" and return "a".

        Example: +/[1 2 3 4]  -->  10
        ................................................................

        a f/b                                             [Over-Neutral]

        This is like "/", but with a neutral element "a" that will be
        returned when "b" is [] or combined with the first element of
        "b" otherwise:

        a f/[]  -->  a
        a f/b   -->  f(...f(f(a;b1);b2)...;bN)

        For example, +/[] will give [], but 0+/[] will give 0.

        Of course, dyadic "/" can also be used to abbreviate an
        expression by supplying a not-so-neutral "neutral element".
        For instance, a++/b can be abbreviated to a+/b.

        If both "a" and "b" are atoms, "a f/b" will give f(a;b).

        Formally, "a f/b" is equal to f/a,b

        Example: 0,/[1 2 3]  -->  [0 1 2 3]
                 1+/[2 3 4]  -->  10
        ................................................................

        f:~a                                                  [Converge]

        Find the fixpoint of f(a), if any. The fixpoint of "f" is a value
        "a" for which f(a) = a. For example,

        {(x+2%x)%2}:~2 

        converges toward the square root of two using Newton's method.
        Starting with x=2:

        (2+2%2)%2              -->  1.5
        (1.5+2%1.5)%2          -->  1.41666
        (1.41666+2%1.41666)%2  -->  1.41421  :"next value is the same"
        (1.41421+2%1.41421)%2  -->  1.41421

        (Of course, the precision of the actual implementation will
         probably be higher.)

        Example: ,/:~["f" ["l" "at"] "ten"]  -->  "flatten"
        ................................................................

        a f:~b                                                   [While]

        Compute b::f(b) while a(b) is true. Formally:

        - if a(b) is false, return b
        - else assign b::f(b) and start over

        Example: {x<1000}{x*2}:~1  -->  1024
        ................................................................

        a f:*b                                                 [Iterate]

        Apply "f" recursively to "b" "a" times. More formally:

        - if "a" is zero, return b
        - else assign b::f(b) and a::a-1 and start over

        Example: 3{1,x}:*[]  -->  [1 1 1]
        ................................................................

        f\a                                                  [Scan-Over]
        a f\b                                        [Scan-Over-Neutral]

        "\" is like "/", but collects intermediate results in a list and
        returns that list. In the resulting list,

        - the first slot will contain a1
        - the second slot will contain f(a1;a2)
        - the third slot will contain f(f(a1;a2);a3)
        - the last slot will contain f(...f(a1;a2)...;aN)
          (which is the result of f/a)

        If only one single argument is supplied, the argument will be
        returned in a list, e.g.: +\1 --> [1].

        "a f\b" is equal to f\a,b.

        Examples:  ,\[1 2 3]  -->  [1 [1 2] [1 2 3]]
                  0,\[1 2 3]  -->  [0 [0 1] [0 1 2] [0 1 2 3]]
        ................................................................

        f\~a                                           [Scan-Converging]

        Monadic \~ is like monadic :~, but returns a list of all
        intermediate results instead of just the end result. The
        last element of the list will be same as the result of a
        corresponding :~ application. For instance:

        {(x+2%x)%2}\~2 

        will produce a list containing a series that converges toward
        the square root of 2.

        Example: ,/\~["a" ["b"] "c"]  -->  [["a" ["b"] "c"]
                                            ["a" "b" "c"]
                                            "abc"]
        ................................................................

        a f\~b                                              [Scan-While]

        This adverb is (almost) like is non-scanning counterpart, :~,
        but it collects intermediate results in a list and returns that
        list.

        However, \~ will only collect values of X that satisfy a(X),
        while :~ will return the first value that does *not* satisfy
        a(X). E.g.:

        {x<10}{x+1}:~1  -->  10
        {x<10}{x+1}:\1  -->  [1 2 3 4 5 6 7 8 9]

        Example: {x<100}{x*2}\~1  -->  [1 2 4 8 16 32 64]
        ................................................................

        a f\*b                                          [Scan-Iterating]

        This adverbs is like its non-scanning counterpart, but collects
        intermediate results in a list and return that list.

        Example: 3{1,x}\*[]  -->  [[] [1] [1 1] [1 1 1]]
        ................................................................

        Multiple Adverbs

        Multiple adverbs can be attached to a verb. In this case, the
        first adverb modifies the verb, giving a new verb, and the next
        adverb modifies the new verb. Note that subsequent adverbs must
        be adverbs of monadic verbs, because the first verb-adverb
        combination in a chain of adverbs forms a monad. So ,/' (Join-
        Over-Each) would work, but ,/:' (Join-Over-Each-Pair) would not,
        because :' expects a dyadic verb.

        Examples:

        +/' (Plus-Over-Each) would apply Plus-Over to each member of a
        list:

        +/'[[1 2 3] [4 5 6] [7 8 9]]  -->  [6 15 24]

        ,/:~ (Flatten-Over-Converging) would apply Flatten-Over until a
        fixpoint is reached:

        ,/:~[1 [2 [3 [4] 5] 6] 7]  -->  [1 2 3 4 5 6 7]

        ,/\~ (Flatten-Over-Scan-Converging) explains why ,/:~ flattens
        any object:

        ,/\~[1 [2 [3 [4] 5] 6] 7]  -->  [[1 [2 [3 [4] 5] 6] 7]
                                          [1 2 [3 [4] 5] 6 7]
                                           [1 2 3 [4] 5 6 7]
                                            [1 2 3 4 5 6 7]]
        ................................................................

        Adverbs and Function Arguments

        Note that function arguments ("x","y","z") cannot be verbs in
        verb-adverb combinations, because they will be eta-expanded!

        E.g.:

        {x'y}({-x};[1 2 3])  :"BZZZT, WRONG!"

        will not work, because it eta-expands "x", thereby creating two
        conflicting instances of "x":

        {{x(x)}'y}({-x};[1 2 3])

        Because the inner "x" gets values from "y", it will try to apply
        "1" to itself, resulting in an error. In cases like this one,
        you have to rename "x" first:

        {[f];f::x;f'y}({-x};[1 2 3])

        ----------------------------------------------------------------
        SEMANTICS : ARRAYS
        ----------------------------------------------------------------

        An array is a list with a symmetric shape, as determined by the
        "^" (Shape) operator. All arrays are lists, but not all lists
        are arrays. For example:

        ^[[1 2]
          [3 4]
          [5 6]]  -->  [3 2]

        is an array of the shape 3,2, or a list of three elements,
        each having a size of two elements. All shapes are given in
        row-major order.

        This is a vector, but not a matrix:

        ^[[1 2]
          [3]
          [4 5]]  -->  [3]

        Above is a list of three elements, because the shape is not
        symmetric at column level ([3] has only one element).

        Of course, arrays may have more than two dimensions:

        ^[[[1 2 3 4]
           [5 6 7 8]]
          [[9 0 1 2]
           [3 4 5 6]]
          [[7 8 9 0]
           [1 2 3 4]]]  -->  [3 2 4]

        ^[5 5 5 5 5]:^0  -->  [5 5 5 5 5]

        (The :^ (Reshape) operator reshapes an object; see [Reshape].)

        ----------------------------------------------------------------
        SEMANTICS : I/O CHANNELS
        ----------------------------------------------------------------

        Input and output in Klong is based on channels. Functions like
        .rl (Read-line) and .p (Print) read and write the current input
        and output channels. The current input channel is called the
        From Channel, and the current output is called the To Channel.

        Initially, the From Channel is connected to .cin, which in turn
        corresponds to the standard input of the Klong interpreter. The
        To Channel is connected to .cout, the standard output of Klong,
        and there is a third channel, .cerr, which is the standard error
        or log channel of the interpreter.

        Here is a simple-minded Unix cat(1) utility that just echoes
        input from the From Channel to the To Channel:

        cat::{.mi{.p(x);.rl()}:~.rl()}

        The .mi function returns truth as long as there is "more input"
        available from the current From Channel. So what this function
        does is "While More-Input, (Print x, Read-Line), starting with
        Read-line".

        Additional input channels can be opened with the Input-Channel
        (.ic) function and selected with the From-Channel (.fc) function.
        Here is a function that types the content of a file:

        type::{.fc(.ic(x));cat()}

        The function opens the input channel "x" and selects it as the
        current From Channel. With the new From Channel established, it
        calls "cat", which now reads from that channel.

        The channel is never closed here. Klong will automatically close
        it at some time.

        Similarly, a new output channel can be established using
        the Output-Channel (.oc) and To Channel (.tc) functions.
        The following function copies file "x" to "y":

        copy::{[of];.tc(of::.oc(y));type(x);.cc(of)}

        Note that "copy" does close the output channel. This is not
        strictly necessary, but makes sure that all output has been
        written to "y" when "copy" returns. Alternatively, the .fl
        function can be used to flush the current To Channel without
        closing it.

        NOTE: in interactive mode, the From and To Channels are reset to
        .cin and ,cout after program run time, but without closing any
        additional channels first. So expressions like

        .tc(.oc("foo"));.p("hello!")

        are not guaranteed to finish their output at any specific time.
        To make sure that output is written, use:

        .tc(T::.oc("foo"));.p("hello!");.cc(T)

        or

        .tc(.oc("foo"));.p("hello!");.fl()

        ----------------------------------------------------------------
        SEMANTICS : OPERATORS
        ----------------------------------------------------------------

        a:=b                                                     [Amend]

        "a" must be a list or string and "b" must be a list where the
        first element can have any type and the remaining elements must
        be integers. It returns a new object of a's type where a@b2
        through a@bN are replaced by b1. When "a" is a string, b1 must
        be a character or a string. The first element of "a" has an
        index of 0.

        When both "a" and b1 are strings, Amend replaces each substring
        of "a" starting at b2..bN by b1. Note that no index b2..bN must
        be larger than #a or a range error will occur. When b1 is
        replaced at a position past (#a)-#b1, the amended string will
        grow by the required amount. For instance:

        "aa":="bc",1 --> "abc".

        Examples:    "-----":=0cx,[1 3]  -->  "-x-x-"
                           [1 2 3]:=0,1  -->  [1 0 3]
                  "-------":="xx",[1 4]  -->  "-xx-xx-"
                         "abc":="def",3  -->  "abcdef"
        ................................................................

        a:-b                                            [Amend-in-Depth]

        :- is like :=, but "a" may be a multi-dimensional array. The :-
        operator replaces one single element in that array. The sequence
        of indices b1..bN is used to locate the target element in an
        N-dimensional array. The number of indices must match the rank
        of the array.

        Example: [[1 2] [3 4]]:-42,[0 1]  -->  [[1 42] [3 4]]
                      [[[0]]]:-1,[0 0 0]  -->  [[[1]]]
        ................................................................

        @a                                                        [Atom]

        @ returns 1, if "a" is an atom and otherwise 0. All objects
        except for non-empty lists and non-empty strings are atoms.

        Examples:      @""  -->  1
                       @[]  -->  1
                      @123  -->  1
                  @[1 2 3]  -->  0
        ................................................................

        :#a                                                       [Char]

        Return the character at the code point "a".

        Monadic :# is an atomic operator.

        Examples: :#64  -->  0cA
                  :#10  -->  :"newline character"
        ................................................................

        a:_b                                                       [Cut]

        Cut the list "b" before the elements at positions given in "a".
        "a" must be an integer or a list of integers. When it is a list
        of integers, its elements must be in monotonically increasing
        order. :_ returns a new list containing consecutive segments of
        "b". 

        When "a" is zero or #b or contains two subsequent equal indices,
        nil (or an empty string if "b" is a string) will be inserted.

        Examples:      2:_[1 2 3 4]  -->  [[1 2] [3 4]]
                  [2 3 5]:_"abcdef"  -->  ["ab" "c" "de" "f"]
                             0:_[1]  -->  [[] [1]]
                           3:_"abc"  -->  ["abc" ""]
                       [1 1]:_[1 2]  -->  [[1] [] [2]]
        ................................................................

        a::b                                                    [Define]

        Assign "b" to the variable "a" and return "b". When a local
        variable named "a" exists, the value will be assigned to it,
        otherwise the global variable "a" will be assigned the value.

        Note that :: cannot be used to assign values to the function
        variables "x", "y", and "z" (they are read-only).

        Examples:        a::[1 2 3];a  -->  [1 2 3]
                  a::1;{[a];a::2}();a  -->  1
        ................................................................

        a%b                                                     [Divide]

        Return the quotient of "a" and "b". The result is always a real
        number, even if the result has a fractional part of 0.

        "%" is an atomic operator.

        Examples: 10%2  -->  5.0
                  10%8  -->  1.25
        ................................................................

        a_b                                                       [Drop]

        When "b" is a list or string, drop "a" elements or characters
        from it, returning the remaining list. Dropping more elements
        than contained in "b" will yield the empty list/string. A
        negative value for "a" will drop elements from the end of "b".

        When "b" is a dictionary, remove the entry with the key "a" from
        it. Dictionary removal is in situ, i.e. the dictionary will be
        modified. Other objects will be copied.

        Examples: 3_[1 2 3 4 5]  -->  [4 5]
                  (-3)_"abcdef"  -->  "abc"
                     17_[1 2 3]  -->  []
                       (-5)_"x"  -->  ""
                          0_[1]  -->  [1]
        ................................................................

        !a                                                   [Enumerate]

        Create a list of integers from 0 to a-1. !0 gives [].

        Examples: !0   -->  []
                  !1   -->  [1]
                  !10  -->  [0 1 2 3 4 5 6 7 8 9]
        ................................................................

        a=b                                                      [Equal]

        Return 1, if "a" and "b" are equal, otherwise return 0.

        Numbers are equal, if they have the same value.
        Characters are equal, if (#a)=#b.
        Strings and symbols are equal, if they contain the same
        characters in the same positions.

        "=" is an atomic operator. In particular it means that it
        cannot compare lists, but only elements of lists. Use "~"
        (Match) to compare lists.

        Real numbers should not be compared with "=". Use "~" instead.

        Examples:             1=1  -->  1
                      "foo"="foo"  -->  1
                        :foo=:foo  -->  1
                          0cx=0cx  -->  1
                  [1 2 3]=[1 4 3]  -->  [1 0 1]
        ................................................................

        &a                                                [Expand/Where]

        Expand "a" to a list of subsequent integers X, starting at 0,
        where each XI is included aI times. When "a" is zero or an
        empty list, return nil. When "a" is a positive integer, return
        a list of that many zeros.

        In combination with predicates this function is also called
        Where, since it compresses a list of boolean values to indices,
        e.g.:

         [1 2 3 4 5]=[0 2 0 4 5]  -->  [0 1 0 1 1]
        &[1 2 3 4 5]=[0 2 0 4 5]  -->  [1 3 4]

        Examples:           &0  -->   []
                            &5  -->   [0 0 0 0 0]
                      &[1 2 3]  -->   [0 1 1 2 2 2]
                  &[0 1 0 1 0]  -->   [1 3]
        ................................................................

        a?b                                                       [Find]

        Find each occurrence of "b" in "a". "a" must be a list, string,
        or dictionary. When "a" is a dictionary, return the value
        associated with the given key. When "a" is a list or string,
        return a list containing the position of each match.

        When both "a" and "b" are strings, return a list containing each
        position of the substring "b" inside of "a". The empty string ""
        is contained between any two characters of a string, even before
        the first and after the last character.

        In any case a return value of nil indicates that "b" is not
        contained in "a", except when "a" is a dictionary. When a key
        cannot be found in a dictionary, Find will return :undefined.
        (See [Undefined].)

        Examples: [1 2 3 1 2 1]?1  -->  [0 3 5]
                        [1 2 3]?4  -->  []
                      "hello"?0cl  -->  [2 3]
                    "xyyyyz"?"yy"  -->  [1 2 3]
                            ""?""  -->  [0]
                      :{[1 []]}?1  -->  []
                       :{[1 2]}?3  -->  :undefined
        ................................................................

        *a                                                       [First]

        Return the first element of "a", i.e. the first element of a
        list or the first character of a string. When "a" is an atom,
        return that atom.

        Examples:  *[1 2 3]  -->  1
                     *"abc"  --> 0ca
                        *""  -->  ""
                        *[]  -->  []
                         *1  -->  1
        ................................................................

        _a                                                       [Floor]

        Return "a" rounded toward negative infinity. When "a" is an
        integer, this is an identity operation. If "a" can be converted
        to integer without loss of precision after rounding, it will be
        converted. Otherwise, a floored real number will be returned.

        Note: loss of precision is predicted by comparing real number
        precision to the exponent, which is a conservative guess.

        Examples:   _123  -->  123
                  _123.9  -->  123
                  _1e100  -->  1.0e+100  :"if precision < 100 digits"
        ................................................................

        a:$b                                                      [Form]

        Convert string "b" to the type of the object of "a". When "b"
        can be converted to the desired type, an object of that type
        will be returned. When such a conversion is not possible, :$
        will return :undefined.

        When "a" is an integer, "b" may not represent a real number.
        When "a" is a real number, a real number will be returned, even
        if "b" represents an integer. When "a" is a character, "b" must
        contain exactly one character. When "a" is a symbol, "b" must
        contain the name of a valid symbol (optionally including a
        leading ":" character).

        :$ is an atomic operator.

        Examples:     1:$"-123"  -->  -123
                    1.0:$"1.23"  -->  1.23
                       0c0:$"x"  -->  0cx
                   "":$"string"  -->  "string"
                   :x:$"symbol"  -->  :symbol
                  :x:$":symbol"  -->  :symbol
        ................................................................

        $a                                                      [Format]

        Write the external representation of "a" to a string and return
        it. The "external representation" of an object is the form in
        which Klong would display it.

        "$" is an atomic operator.

        Examples:    $123  -->  "123"
                  $123.45  -->  "123.45"
                  $"test"  -->  "test"
                     $0cx  -->  "x"
                    $:foo  -->  ":foo"
        ................................................................

        a$b                                                    [Format2]

        Dyadic "$" is like its monadic cousin, but also pads its result
        with blanks. The minimal size of the output string is specified
        in "a", which must be an integer. "b" is the object to format.
        When the value of "a" is negative, the result string is padded
        to the right, else it is padded to the left.

        When "a" is real number of the form n.m and "b" is also a real
        number, the representation of "b" will have "n" integer digits
        and "m" fractional digits. The integer part will be padded with
        blanks and the fractional part will be padded with zeros.

        "$" is an atomic operator.

        Examples:     0$123  -->  "123"
                  (-5)$-123  -->  " -123"
                    5$"xyz"  -->  "xyz  "
                  (-5)$:foo  -->  " :foo"
                 5.3$123.45  -->  "  123.450"
        ................................................................

        >a                                                  [Grade-Down]
        <a                                                    [Grade-Up]

        Impose the given order ("<" = ascending, ">" = descending") onto
        the elements of "a", which must be a list or string. Return a
        list of indices reflecting the desired order. Elements of "a"
        must be comparable by dyadic "<" (Less).

        In addition, "<" and ">" will compare lists by comparing their
        elements pairwise and recursively. E.g. [1 [2] 3] is considered
        to be "less" than [1 [4] 0], because 1=1 and 2<4 (3>0 does not
        matter, because 2<4 already finishes the comparison).

        When "a" is a string, these operators will grade its characters.

        To sort a list "a", use a@<a ("a" At Grade-Up "a") or a@>a.

        Examples:     <[1 2 3 4 5]  -->  [0 1 2 3 4]
                      >[1 2 3 4 5]  -->  [4 3 2 1 0]
                   <"hello, world"  -->  [6 5 11 1 0 2 3 10 8 4 9 7]
                    >[[1] [2] [3]]  -->  [2 1 0]
        ................................................................

        =a                                                       [Group]

        Return a list of lists ("groups") where each group contains the
        index of each occurrence of one element within "a". "a" must be
        a list or string. The indices of all elements of "a" that are
        equal according to "~" (Match) will appear in the same group in
        ascending order.

        ="" and =[] will yield [].

        Examples:   =[1 2 3 4]  -->  [[0] [1] [2] [3]]
                  ="hello foo"  -->  [[0] [1] [2 3] [4 7 8] [5] [6]]
        ................................................................

        a@b                                                   [At/Index]
        a@b                                                   [At/Apply]

        Extract one or multiple elements from "a" at (zero-based)
        positions given in "b". In this case "a" may be a list or a
        string.

        When "b" is an integer, extract a single element at the given
        position and return it.

        When "b" is a list, return a list containing the extracted
        elements. All members of "b" must be integers in this case.
        The order of indices in "b" does not matter. The same index
        may occur multiple times.

        When "a" is a function, "b" (if it is an atom) or the members
        of "b" (if it is a list) will be passed as arguments to the
        function and the result will be returned.

        Examples:         [1 2 3 4 5]@2  -->  3
                    [1 2 3 4 5]@[1 2 3]  -->  [2 3 4]
                    [1 2 3 4 5]@[0 0 0]  -->  [1 1 1]
                  "hello world"@[3 7 2]  -->  "lol"
                               {x}@:foo  -->  :foo
                         {y+x*x}@[2 3]   -->  7
        ................................................................

        a:@b                                            [Index-in-Depth]

        :@ is like "@" but, when applied to an array, extracts a single
        element from a multi-dimensional array. The indices in "b" are
        used to locate the element. The number of indices must match
        the rank of the array.

        If "a" is a function, :@ is equal to "@".

        Examples: [[1 2] [3 4]]:@[0 1]  -->  2
                      [[[1]]]:@[0 0 0]  -->  1
                        {y+x*x}:@[2 3]  -->  7
        ................................................................

        a:%b                                            [Integer-Divide]

        Return the integer part of the quotient of "a" and "b". Both "a"
        and "b" must be integers. The result is always an integer.

        Formally, a = (b*a:%b) + a!b .

        ":%" is an atomic operator.

        Examples: 10:%2  -->  5
                  10:%8  -->  1
        ................................................................

        a,b                                                       [Join]

        The "," operator joins objects of any type, forming lists or
        strings.

        If "a" and "b" are lists, append them.
        If "a" is a list and "b" is not, attach "b" at the end of "a".
        If "a" is a not list and "b" is one, attach "a" to the front of
        "b".
        If "a" and "b" are strings, append them.
        If "a" is a string and "b" is a char, attach "b" to the end of
        "a".
        If "a" is a char and "b" is a string, attach "a" to the front of
        "b".

        If "a" is a dictionary and "b" is a tuple (a list of two members)
        or vice versa, add the tuple to the dictionary. Any entry with
        the same key will be replaced by the new entry. The head of the
        tuple is the key and the second element is the payload.

        Otherwise, create a tuple containing "a" and "b" in that order.

        Join always returns a fresh list, but dictionaries will be
        updated by replacing old entries in situ.

        Examples:  [1 2 3],[4 5 6]  -->  [1 2 3 4 5 6]
                           1,[2 3]  -->  [1 2 3]
                           [1 2],3  -->  [1 2 3]
                       "abc","def"  -->  "abcdef"
                          "ab",0cc  -->  "abc"
                          0ca,"bc"  -->  "abc"
                               1,2  -->  [1 2]
                             "a",1  -->  ["a" 1]
                       [[1 2 3]],4  -->  [[1 2 3] 4]
                           1,2,3,4  -->  [1 2 3 4]
                    [1 2],:{[1 0]}  -->  :{[1 2]}
                    :{[1 0]},[1 2]  -->  :{[1 2]}
        ................................................................

        a<b                                                       [Less]

        Return 1, if "a" is less than "b", otherwise return 0.

        Numbers are compared by value.
        Characters are compared by ASCII code.
        Strings and symbols are compared lexicographically.

        "<" is an atomic operator; it cannot compare lists, but only
        elements of lists.

        Examples:              1<2  -->  1
                       "bar"<"foo"  -->  1
                         :abc<:xyz  -->  1
                           0c0<0c9  -->  1
                   [1 2 3]<[1 4 3]  -->  [0 1 0]
        ................................................................

        ,a                                                        [List]

        "," packages any object in a single-element list.

        Examples:    ,1  -->  [1]
                  ,:foo  -->  [:foo]
                  ,"xyz" -->  ["xyz"]
                   ,[1]  -->  [[1]]
        ................................................................

        a~b                                                      [Match]

        "~" is like "=", but can also compare lists and real numbers. It
        uses "=" (Equal) to compare integers, characters, symbols and
        strings.

        Two real numbers "a" and "b" match, if they are "sufficiently
        similar", where the exact definition of "sufficiently similar"
        is too complex to be discussed here. For the curious reader:
        the current implementation uses a relative epsilon algorithm.
        For instance, given

        sq2::{(x+2%x)%2}:~1 :"square root of 2"

        the following expression will be true:

        sq2~sq2+10*.e

        although the operands of Match differ by 10 times Epsilon.

        Two lists match if all of their elements match pairwise. "~"
        descends into sublists.

        Examples:                  1~1  -->  1
                           "foo"~"foo"  -->  1
                             :foo~:foo  -->  1
                               0cx~0cx  -->  1
                       [1 2 3]~[1 2 3]  -->  1
                   [1 [2] 3]~[1 [4] 3]  -->  0
        ................................................................

        a|b                                                     [Max/Or]

        Return the larger one of two numbers.

        When both "a" and "b" are in the set {0,1} (booleans), then "|"
        acts as an "or" operator, as you can easily prove using a truth
        table:

        a  b  max/or
        0  0    0
        0  1    1
        1  0    1
        1  1    1

        Dyadic "|" is an atomic operator.

        Examples:       0|1  -->  1
                   123|-123  -->  123
                    1.0|1.1  -->  1.1
        ................................................................

        a&b                                                    [Min/And]

        Return the smaller one of two numbers.

        When both "a" and "b" are in the set {0,1} (booleans), then "&"
        acts as an "and" operator, as you can easily prove using a truth
        table:

        a  b  min/and
        0  0     0
        0  1     0
        1  0     0
        1  1     1

        Dyadic "&" is an atomic operator.

        Examples:       0&1  -->  0
                   123&-123  -->  -123
                    1.0&1.1  -->  1.0
        ................................................................

        a-b                                                      [Minus]

        Subtract "b" from "a" and return the result. "a" and "b" must be
        numbers.

        "-" is an atomic operator.

        Examples:  12-3  -->  9
                  12--3  -->  15
                  1-0.3  -->  0.7
        ................................................................

        a>b                                                       [More]

        Return 1, if "a" is greater than "b", otherwise return 0.

        See "<" (Less) for details on comparing objects.

        ">" is an atomic operator; it cannot compare lists, but only
        elements of lists.

        Examples:              2>1  -->  1
                       "foo">"bar"  -->  1
                         :xyz>:abc  -->  1
                           0c9>0c0  -->  1
                   [1 4 3]>[1 2 3]  -->  [0 1 0]
        ................................................................

        -a                                                      [Negate]

        Return 0-a; "a" must be a number.

        "-" is an atomic operator.

        Examples:    -1  -->  -1
                  -1.23  -->  -1.23
        ................................................................

        ~a                                                         [Not]

        Return the negative truth value of "a", as explained in the
        section on CONDITIONALS. It will return 1 for 0, [], and "",
        and 0 for all other values.
        
        Examples:    ~0  -->  1
                     ~1  -->  0
                    ~[]  -->  1
                  ~:foo  -->  0
        ................................................................

        a+b                                                       [Plus]

        Add "b" to "a" and return the result. "a" and "b" must both be
        numbers.

        Dyadic "+" is an atomic operator.

        Examples:  12+3  -->  15
                  12+-3  -->  9
                  1+0.3  -->  1.3
        ................................................................

        a^b                                                      [Power]

        Compute "a" to the power of "b" and return the result. Both "a"
        and "b" must be numbers. The result of a^b cannot be a complex
        number.

        Dyadic "^" is an atomic operator.

        Examples:   2^0  -->  1
                    2^1  -->  2
                    2^8  -->  256
                   2^-5  -->  0.03125
                  0.3^3  -->  0.027
                  2^0.5  -->  1.41421356237309504
        ................................................................

        ?a                                                       [Range]

        Return a list containing unique elements from "a" in order of
        appearance. "a" may be a list or string.

        Examples:   ?[1 2 3 4]  -->  [1 2 3 4]
                  ?[1 1 1 2 2]  -->  [1 2]
                  ?"aaabbcccd"  -->  "abcd"
        ................................................................

        %a                                                  [Reciprocal]

        Return 1%a. "a" must be a number.

        "%" is an atomic operator.

        Examples:    %1  -->  1.0
                     %2  -->  0.5
                   %0.1  -->  10.0
        ................................................................

        a:^b                                                   [Reshape]

        :^ reshapes "b" to the shape specified in "a". The shape is
        specified in the form returned by the "^" (Shape) operator: a
        list of dimensions in row-major order.

        The operand "b" may be in any shape. The elements of the new
        array will be taken from "b" in sequential order:

        [3 3]:^[1 2 3 4 5 6 7 8 9]  -->  [[1 2 3]
                                          [4 5 6]
                                          [7 8 9]]

        When the source array contains more elements that can be stored
        in an array of the shape "a", excess elements in "b" will be
        ignored. When the source array contains too few elements, :^
        will cycle through the source object, repeating the elements
        found there:

        [3 3]:^[0 1]  -->  [[0 1 0]
                            [1 0 1]
                            [0 1 0]

        When the value -1 appears in the shape parameter "a", it denotes
        half the size of the source vector, e.g.:

        [-1 2]:^!10  -->  [[0 1] [2 3] [4 5] [6 7] [8 9]]
        [2 -1]:^!10  -->  [[0 1 2 3 4] [5 6 7 8 9]]

        Both "a" and "b" may be atoms:

        5:^1  -->  [1 1 1 1 1]

        but when "b" is an atom (or a single-argument vector), then "a"
        may not contain the value -1.

        0:^x is an identity operation returning x.

        Examples:           5:^:x  -->  [:x :x :x :x :x]
                         [3]:^[1]  -->  [1 1 1]
                  [2 2 2]:^[1 2 3] -->  [[[1 2] [3 1]] [[2 3] [1 2]]]
                    [2]:^[[1 2 3]] -->  [[1 2 3] [1 2 3]]
        ................................................................

        a!b                                                  [Remainder]

        Return the truncated division remainder of "a" and "b". Both
        "a" and "b" must be integers.

        Formally, a = (b*a:%b) + a!b .

        Dyadic "!" is an atomic operator.

        Examples:    7!5  -->  2
                    7!-5  -->  2
                  (-7)!5  --> -2
                   -7!-5  --> -2
        ................................................................

        |a                                                     [Reverse]

        Return a new list/string that contains the elements of "a" in
        reverse order. When "a" is neither a list nor a string, return
        it unchanged.

        Examples:       |[1 2 3]  -->  [3 2 1]
                  |"hello world"  -->  "dlrow olleh"
                              |1  -->  1
        ................................................................

        a:+b                                                    [Rotate]

        Rotate the list or string "b" by "a" elements. "a" must be an
        integer. When "a" is positive, rotate elements to the "right",
        i.e. drop elements from the end of "b" and append them to the
        front. When "a" is negative, rotate "b" to the left, i.e. drop
        from the beginning, append to the end.

        "a" may be greater than #b. In this case, the number of elements
        rotated will be a!#b.

        Note that n:+M rotates the rows of a matrix M (i.e. it rotates
        it vertically); to rotate its columns (horizontally), use n:+:\M
        (Rotate-Each-Left).

        Examples:           1:+[1 2 3 4 5]     -->  [5 1 2 3 4]
                            (-1):+[1 2 3 4 5]  -->  [2 3 4 5 1]
                       1:+[[1 2] [4 5] [5 6]]  -->  [[1 2] [4 5] [5 6]]
                   {1:+x}'[[1 2] [4 5] [5 6]]  -->  [[2 1] [5 4] [6 5]]
        ................................................................

        ^a                                                       [Shape]

        Return the shape of "a". The shape of an atom is 0. The shape of
        a list L of atoms is ,#L. Such a list is also called a 1-array
        or a vector. The shape of a list of lists of equal length (M) is
        (#M),#*M. Such a list is called a 2-array or a matrix. A list of
        lists of unequal length is a vector.

        This principle is extended to higher dimensions. An N-array A is
        is an array with equal-sized sub-arrays in each dimension. Its
        shape is (#A),(#*A),...,(#*...*A), where there are N-1 "*"
        operators in the last group of that expression. All shapes are
        written in row-major notation.

        For example:

        [1 2 3 4 5]    is a vector (shape [5])

        [[1 2]
         [2 4]
         [5 6]]        is a matrix (shape [3 2])

        [[[1 2 3 4] 
          [5 6 7 8]]
         [[9 0 1 2]
          [3 4 5 6]]
         [[7 8 9 0]
          [1 2 3 4]]]  is a 3-array (shape [3 2 4])

        [[1] [2 3]]    is a vector (shape [2])

        The shape of a string S is ,#S. A list of equally-sized strings
        is a matrix of characters. Strings may form the innermost level
        of higher-dimensional arrays.

        Examples:        ^1  -->  0
                      ^:xyz  -->  0
                       ^[0]  -->  [1]
                   ^[1 2 3]  -->  [3]
                   ^"hello"  -->  [5]
                   ^[[1 2]
                     [3 4]
                     [5 6]]  -->  [3 2]
                   ^[1 [2]]  -->  [2]
                  ^["abcd"
                    "efgh"]  -->  [2 4]
        ................................................................

        #a                                                        [Size]

        Return the size/magnitude of "a".

        For lists, the size of "a" is the number of its elements.
        For strings, the size is the number of characters.
        For numbers, the size is the magnitude (absolute value).
        For characters, the size is the ASCII code.

        Examples:     #[1 2 3]  -->  3
                  #[1 [2 3] 4]  -->  3
                  #"123456789"  -->  9
                         #-123  -->  123
                          #0cA  -->  65
        ................................................................

        a:#b                                                     [Split]

        Split a list or string "b" into segments of the sizes given in
        "a". If "a" is an integer, all segments will be of the same size.
        If "a" is a list of more than one element, sizes will be taken
        from that list. When there are more segments than sizes, :# will
        cycle through "a". The last segment may be shorter than
        specified.

        Examples:         2:#[1 2 3 4]  -->  [[1 2] [3 4]]
                          3:#[1 2 3 4]  -->  [[1 2 3] [4]]
                          3:#"abcdefg"  -->  ["abc" "def" "g"]
                  [1 2]:#[1 2 3 4 5 6]  -->  [[1] [2 3] [4] [5 6]]
        ................................................................

        a#b                                                       [Take]

        Extract "a" elements from the front of "b". "a" must be an
        integer and "b" must be a list or string. If "a" is negative,
        extract elements from the end of "b". Extracting more elements
        than contained in "b" will fill the extra slots by cycling
        through "b". Taking 0 elements will result in an empty list
        or string.

        Examples:     1#[1 2 3]  -->  [1]
                      2#[1 2 3]  -->  [1 2]
                      5#[1 2 3]  -->  [1 2 3 1 2]
                   (-2)#[1 2 3]  -->  [2 3]
                   (-5)#[1 2 3]  -->  [2 3 1 2 3]
                     3#"abcdef"  -->  "abc"
                  (-3)#"abcdef"  -->  "def"
                           0#[]  -->  []
                           0#""  -->  ""
        ................................................................

        a*b                                                      [Times]

        Return "a" multiplied by "b". "a" and "b" must both be numbers.

        Dyadic "*" is an atomic operator.

        Examples:   3*4  -->  12
                   3*-4  -->  -12
                  0.3*7  -->  2.1
        ................................................................

        +a                                                   [Transpose]

        Return the transpose of the matrix (2-array) "a".

        Examples:     +[[1] [2] [3]]  -->  [[1 2 3]]
                  +[[1 2 3] [4 5 6]]  -->  [[1 4] [2 5] [3 6]]
                                 +[]  -->  []

        ................................................................

        :_a                                                  [Undefined]

        Return truth, if "a" is undefined, i.e. the result of an
        operation that cannot yield any meaningful result, like
        division by zero or trying to find a non-existent key in
        a dictionary. Else return 0.

        Examples:        :_1%0  -->  1
                  :_:{[1 2]}?3  -->  1
                      :_:valid  -->  0

        ----------------------------------------------------------------
        SEMANTICS : FUNCTIONS
        ----------------------------------------------------------------

        .ac(a)                                          [Append-Channel]

        See [Output-Channel].
        ................................................................

        .cc(a)                                           [Close-Channel]

        Close the input or output channel "a", returning []. Closing an
        already closed channel has no effect. A channel will be closed
        automatically when no variable refers to it and it is not the
        current From or To Channel.
        ................................................................

        .comment(a)                                            [Comment]

        Read and discard lines until the current line starts with the
        string specified in "a". Also discard the line containing the
        end-of-comment marker and return "a".

        Example: .comment("end-of-comment")
                 this will be ignored
                 this, too: *%(*^#)&(#
                 end-of-comment
        ................................................................

        .d(a)                                                  [Display]

        See [Write].
        ................................................................

        .df(a)                                             [Delete-File]

        Delete the file specified in the string "a". When the file
        cannot be deleted (non-existent, no permission, etc), signal
        an error.
        ................................................................

        .E(a)                                                 [Evaluate]

        Evaluate the Klong program contained in the string "a" and
        return its result. This is a direct interface to the Klong
        system, e.g. .E("a::123");a will yield 123.
        ................................................................

        .fc(a)                                            [From-Channel]
        .tc(a)                                              [To-Channel]

        .fc selects input channel "a" for reading and .tc selects
        output channel "a" for writing, i.e. these functions select a
        new From and To Channel, respectively. All input/output will
        be redirected to the given channel. Both function will return
        the channel that was previously in effect.

        When a false value (0,[],"") is passed to these functions, they
        restore the default From or To Channel (.cin or .cout).
        ................................................................

        .fl()                                                    [Flush]

        Make sure that all output sent to the To Channel is actually
        written to the associated file or device ("flush" the channel).
        ................................................................

        .ic(a)                                           [Input-Channel]

        Open the file named in the string "a", link it to an input
        channel, and return that channel. Opening a non-existent file
        is an error.
        ................................................................

        .l(a)                                                     [Load]

        Load the content of the file specified in the string "a" as if
        typed in at the interpreter prompt.

        Klong will try the names "a", and a,".kg", in all directories
        specified in the KLONGPATH environment variable. Directory names
        in KLONGPATH are separated by colons.

        When KLONGPATH is undefined, it defaults to ".:lib".

        A program can be loaded from an absolute or relative path
        (without a prefix from KLONGPATH) by starting "a" with a "/"
        or "." character.

        .l will return the last expression evaluated, i.e. it can be
        used to load the value of a single expression from a file.
        ................................................................

        .mi(a)                                              [More-Input]

        This function returns 1, if the From Channel is not exhausted
        (i.e. no reading beyond the EOF has been attempted on that
        channel). When no more input is available, it returns 0.

        This is a "negative EOF" function.
        ................................................................

        .module(a)                                              [Module]

        Delimit a module. See MODULES, below.
        ................................................................

        .oc(a)                                          [Output-Channel]
        .ac(a)                                          [Append-Channel]

        Both of these functions open a file named in the string "a",
        link it to an output channel, and return that channel. The
        difference between them is that .oc truncates any existing
        file and .ac appends to it.
        ................................................................

        .pc()                                            [Process-Clock]

        Return the process time consumed by the Klong interpreter so
        far. The return value is in seconds with a fractional part
        whose resolution depends on the operating environment and may
        be anywhere between 50Hz and 1MHz.

        The program {[t0];t0::.pc();x@[];.pc()-t0} measures the process
        time consumed by the nilad passed to it.

        This function is not avaliable in the Plan 9 port of Klong.
        ................................................................

        .p(a)                                                    [Print]

        Pretty-print the object "a" (like Display) and then print a
        newline sequence. .p("") will just print a newline.
        ................................................................

        .r()                                                      [Read]

        Read a single data object from the currently selected input port
        and return it. The object being read may be an atom or a list.
        When it is a dictionary or list, the input may span multiple
        lines.
        ................................................................

        .rl()                                                [Read-Line]

        Read a line from the From Channel and return it as a string.
        If there is a line separator at the end of the line, it will
        be stripped from the string.
        ................................................................

        .rn()                                            [Random-Number]

        Return a random number x, such that 0 <= x < 1.
        ................................................................

        .rs(a)                                             [Read-String]

        .rs is like .r, but reads its input from the string "a". It is
        intended for the converting sequentialized compound data objects,
        such as lists, arrays, and dictionaries, back to their internal
        forms.
        ................................................................

        .sys(a)                                                 [System]

        Pass the command in the string "a" to the operating system for
        execution and return the exit code of the command. On a Unix
        system, the command would be executed as

        sh -c "command"

        and an exit code of zero would indicate success.
        ................................................................

        .tc(a)                                              [To-Channel]

        See [From-Channel].
        ................................................................

        .w(a)                                                    [Write]
        .d(a)                                                  [Display]

        .d and .w both write "a" to the currently selected output port.
        However, .w writes a "readable" representation of the given
        object and .d pretty-prints the object. The "readable" output
        is suitable for reading by .r.

        For most types of object there is no difference. Only strings
        and characters are printed in a different way:

        Object       | .d(Object) | .w(Object)
        ----------------------------------------
        0cx          |  x         | 0cx
        "test"       |  test      | "test"
        "say ""hi""" |  say "hi"  | "say ""hi"""

        For some objects, there is no readable representation, including
        functions, operators, the undefined object, and the "end of file"
        object. A symbolic representation will be printed for those:
        :nilad, :monad, :dyad, :triad, :undefined, :eof.

        None of these functions terminates its output with a newline
        sequence. Use .p (Print) to do so.
        ................................................................

        .x(a)                                                     [Exit]

        Terminate the Klong interpreter, returning "success" to the
        operating system, if "a" is false (0, [], "") and "failure",
        if "a" is not false.

        ----------------------------------------------------------------
        SEMANTICS : VARIABLES
        ----------------------------------------------------------------

        .a                                                   [Arguments]

        This variable holds a list of strings containing the command
        line arguments passed to a Klong program.
        ................................................................

        .cin                                             [Input-Channel]
        .cout                                           [Output-Channel]
        .cerr                                            [Error-Channel]

        These variables are bound to the standard input (.cin), standard
        output (.cout), and standard error (.cerr) channels of the Klong
        process. They can be selected for input or output using the
        From-Channel (.fc) and To-Channel (.tc) functions.

        The standard I/O channels cannot be closed.
        ................................................................

        .cols                                                  [Columns]

        This variable stores the number of columns of the screen on
        which the Klong session is running. It defaults to 80. This
        variable is used by the line editor, if compiled in and enabled
        (see .edit).
        ................................................................

        .e                                                     [Epsilon]

        .e is the smallest value by which two real numbers 0.1 <= x < 1
        can differ. For numbers smaller than 0.1, there would be a
        smaller difference and number x>=1 cannot differ by .e, because
        1+.e --> 1. the actual value of .e is implementation-dependent.
        On a 9-digit implementation, it would be 0.000000001 (1e-9).

        The logarithm to base 10 of %.e (ln(%.e)%ln(10)) equals the
        number of digits in the mantissa of a real number (this is
        exactly the exponent in the scientific notation of %.e).
        ................................................................

        .edit                                                   [Editor]

        When this variable set to a true value AND the line editor is
        compiled into the Klong executable, then line editing and
        history will be enabled on the Klong prompt. See the section on
        LINE EDITING for details.
        ................................................................

        .f                                                    [Function]

        The variable .f is always bound to the function that is currently
        being computed, so it allows you to write anonymous recursive
        functions:

        {:[0=x;[];1,.f(x-1)]}

        Note that .f is lexically bound to the innermost function, so

        {:[@x;0;1+|/{.f(x)}'x]}
                     ^^^^^
        would diverge. (But the effect here is due to unnecessary eta
        expansion; {:[@x;0;1+|/.f'x]} would work fine.)
        ................................................................

        .fastpow                                            [Fast-Power]

        When this variable set to a true value, then expressions of the
        form x^y will compile to .pow(x;y), which makes computations
        involving powers of real numbers much faster (about eight times
        on the author's hardware).

        Setting .fastpow::0 will disable this feature and restore the
        previous behavior of Klong, just in case.
        ................................................................

        .h                                                        [Host]

        This variable holds a unique symbol identifying the host system
        running the Klong process. Currently, this is either :unix or
        :plan9.
        ................................................................

        it                                                          [It]

        In interactive mode, "it" always holds the value of the most
        recent successful computation. See also: INTERACTION, below.

        ----------------------------------------------------------------
        SEMANTICS : MODULES
        ----------------------------------------------------------------

        Klong's module mechanism is extremely simple. Its only goal is
        to protect mutually dependent definitions inside of a module
        from redefinition. It also allows to create (non-function)
        variables that are local to the module. A module begins with

        .module(:name)

        where :name names the module. A module ends with

        .module(0)

        Here is a sample module.       It will be rewritten
                                       internally as follows:
        .module(:foo)
        a::1                           a`foo::1;          a::a`foo
        g::{a}                         g`foo::{a`foo};    g::g`foo
        f::{g()}                       f`foo::{g`foo()};  f::f`foo
        s::{a::x}                      s`foo::{a`foo::x}; s::s`foo
        .module(0)

        Note that a`b is not a valid Klong symbol, it is just a notation
        used by the interpreter to indicate that "a" is a symbol of the
        module "b".

        Behavior is as follows:

        Redefining any of the variables "a", "g", "f", "s" after the
        end of the module will not change the values of those variables
        inside of the module. E.g.:

        a::2;f()  -->  1
        g::0;f()  -->  1

        The function "s" will only affect the "a" of "foo". If there is
        a variable named "a" outside of "foo", it will not be affected:

        a::0
        s(2)
        a    -->  0
        f()  -->  2

        So a module just creates a closed namespace that allows you to
        refactor more complex programs without having to worry about
        later (accidental) redefinition of local functions and variables.

        Modules may not be nested. When loading external modules,
        they must be loaded *before* opening a new module, e.g.:

        .l("external")
        .module(:local)
        :"..."
        .module(0)

        Each module can access all objects defined earlier than the
        module, even objects defined inside of other modules. There
        is no "import" mechanism. For example,

        .module(:foo)
        bar::[1 2 3]
        .module(0)
        .module(:baz)
        goo::bar  :" this refers to the 'bar' of 'foo' "
        .module

        will set the variable "goo" of the module "baz" to [1 2 3].
        ................................................................

        Forward References

        Mutual recursion in a module will create a forward reference,
        like the reference to "o" in "e" in the following module:

        .module(:foo)
        e::{:[0=x;1:|1=x;0;o(x-1)]}
        o::{:[0=x;0:|1=x;1;e(x-1)]}
        .module(0)

        In this case, "o" will only be local to the module if it was
        undefined when the module was opened. If there already exists a
        definition of "o" when the module :foo is opened, that instance
        of "o" will be referred to in :foo.

        To explicitly refer to o`foo (the "o" inside of the module), a
        dummy definition of "o" should be inserted before the first
        reference to it:

        .module(:foo)
        o::0
        e::{:[0=x;1:|1=x;0;o(x-1)]}
        o::{:[0=x;0:|1=x;1;e(x-1)]}
        .module(0)

        ----------------------------------------------------------------
        INTERACTION
        ----------------------------------------------------------------

        ]! command                                               [Shell]

        Pass the given command to the Unix shell.
        ................................................................

        ]a topic                                               [Apropos]
        ]h topic                                                  [Help]

        ]htopic is short for help("topic"). In addition, ]hall will
        list all available help texts. The "topic" must be an operator
        symbol or operator name (e.g. :: or Define).
        ................................................................

        ]i dir                                               [Inventory]

        List all *.kg files (Klong source programs) in the given
        directory. When no directory is given, it defaults to the first
        element of the KLONGPATH variable. The ]i command depends on a
        Unix shell and the "ls" utility (it does "cd dir; ls *.kg").
        ................................................................

        it                                                          [It]

        This variable holds the result of the most recent successful
        computation, so you do not have to re-type or copy-paste the
        previous result. E.g.:

                {(x+2%x)%2}:~2
        1.41421356237309504
                it^2
        1.99999999999999997
        ................................................................

        ]l file                                                   [Load]

        ]lfile is short for .l("file").
        ................................................................

        ]q                                                        [Exit]

        ]q is short for .x(0). However, end-of-file (control-D on Unix)
        typically also works.
        ................................................................

        ]t file                                             [Transcript]

        Start appending user input and computed values to the given file.
        When no file is given, stop transcript. Input will be prefixed
        with a TAB (HT) character in the transcript file.

        ----------------------------------------------------------------
        INTERACTION : LINE EDITING
        ----------------------------------------------------------------

        The Klong system has an (optional) line editor that can be
        compiled into the Klong executable. When compiled-in, the editor
        is enabled by default, but can be disabled by setting .edit::0.

        Only .cols-10 characters are available for editing. This may
        change in a later release.

        When enabled, the following (mostly EMACS-like) keys can be used
        for line editing:

        [control-A]  move to the beginning of the line
        [control-B]  move one char to the left (backward)
        [control-F]  move one char to the right (forward)
        [control-E]  move to the end of the line

        [control-H]  delete character to the left
        [control-U]  delete entire line

        [control-C]  abort input, return to prompt
        [control-D]  delete char; if line is empty, exit Klong

        [control-P]  move to previous history entry (*)
        [control-N]  move to next history entry (*)

        (*) These commands work only when the cursor is at the end or
            at the beginning of the line.

        ================================================================
        |                  This is the end, my friend                  |
        ================================================================

contact  |  privacy