Clip

Clip is a functional language designed for both elegance and brevity. It was inspired by CJam, Lisp, Iota, and Pyth, in that order.

A compiler can be found here. Run using, or omit the filename to run in a REPL environment.

This page is written fairly technically. Some examples are located here.

Functions and suppliers
A Clip program consists of one or more named things, which can be suppliers or functions.

A named supplier is indicated by a left-bracket ([) followed by an upper case letter: [S+3 4 This defines S as the sum of 3 and 4.

A named function is indicated by a left bracket, an upper case letter, and a lower case letter: [Fx+3x This defines F as the sum of 3 and the input value. This can then be called using F4 which returns 7.

Each program is automatically prefixed by [M, thus defining M. When a program is run, it prints the value of M: *8F2[Fx+3x This returns the product of 8 and the function F applied to 2, where F is the sum of 3 and the input. Thus, the program prints 40.

If M includes a lower-case x, it is initialized to treat x as the input variable: *8x is treated as: [Mx*8x

There are also anonymous functions. These are written as a left-bracket followed by a lower case letter. +2[d*3d]5 This creates an anonymous "tripling" function, which is applied to 5.

If a bracket is followed by neither a lower-case nor upper-case letter, it is given a placeholder value at the beginning and end: +2[*3]5 This is the same as above.

Program flow
Each function, when called, evaluates each of its objects in order.

If a function hits a backtick (`) or right-bracket (]), it is returned without being evaluated.
 * If the first object is not a function, it is returned. Otherwise, it is a function, which is applied to -
 * If the second object is not a function, it is returned. Otherwise, it is a function, which is applied to -
 * ... and so on.

An if statement consists of a question mark, an if-clause, a then-clause, a right-bracket, an else-clause, and another right-bracket. If a function hits a question mark, it gets the next result. If it is truthy (not 0 or an empty list), it returns the next value, and then jumps ahead to the second right-bracket. Otherwise, it jumps to the first right-bracket, and continues from there.

?xx]"empty"] Accepts an input. If it isn't empty, it's outputted. If its is empty, it prints "empty".

Types
There are three main data types, all of which are immutable.

Numbers
Numbers can be of two types: numeric or character. There is rarely a difference, except when printing. Numerics are indicated in code using literals, such as 0, 5, -325, 325.142, -12435.12e4, or 325e-2. Characters literals consist of an apostrophe and another character, such as 'a, '', or '&. A number's ischar is whether it is of the character subtype.

Lists
Lists can be arbitrarily nested. There are no list literals except when consisting of just characters, but they can be approximated using the following technique: Start with the { constant, which means an empty ListBuilder. A ListBuilder is a function which appends each object it meets. Finally, use the backtick to escape the ListBuilder, which has the useful side effect of turning it into an array: {1 2 3 'a 'b` Lists of just characters (henceforth known as strings) can be declared as literals using quotation marks. Escape a quotation mark with a period, and a period with two periods. Also, a period followed by an upper case U becomes a period followed by a lower case u, and a period followed by an equals sign becomes a period and a hyphen. "abc de.".. .U..U .=..=" is actually: abc de". .u.U.-.=

Functions
There are a few types of functions, including named and anonymous ones. Others are pre-initialized to constants (such as + or *), and some are created as the results of other functions.

All functions have exactly one argument. For example, + is a function which takes a single number, and returns another function, which takes another number, and returns the sum. Thus, +1 yields the successor function, and +1 2 gives 3.

Most functions and suppliers are pure; that is, they have no observable side-effects and return the same result for the same input, although there are a few exceptions.

Equality
Two numbers are equal if they are mathematically equal, regardless of their ischars. Note that equality of non-integer values is often fraught. For example, =3 *3 /1 3 is false.

Two arrays are equal if they have the same length and corresponding elements are equal.

Two functions are equal if they come from the same declaration. For example, +` equals +`, and named functions equal themselves, as do anonymous functions. However, functions produced from other sources are rarely reflexive. For example, +3` does not equal +3`.

Comparison
Numbers are ordered as expected. Arrays are sorted by element, so "abb" < "abbd" < "abc" < "abca". If corresponding elements are incomparable, an error is triggered.

Boolean values
Numbers are true if they do not equal zero. Arrays are true if they have at least one element, even if that element is false. Functions are always true.

Constants
Constants include named functions and suppliers. There are many default constants as well, as shown in the table below. For simplicity's the sake, the table sometimes refers to a function accepting multiple arguments, although in truth it only accepts one, as explained above. Also, when something is said to be done to a list, the original list is actually left intact; the change is done to a copy of the list which is returned.

Compiling
When a program is compiled, a number of things happen, in the following order:
 * All comments are removed. .-Comments look like this-.
 * Unicode substitution takes place. For each .u present, the next four digits are interpreted as a hexadecimal character code.
 * Strings and character literals are identified.
 * Named functions and suppliers are separated.
 * Right-braces are converted into right-brackets and backticks ( } -> ]` ).
 * Missing right-brackets are placed.
 * Number literals are identified.
 * The main thing is given the name M and wrapped in brackets. If it contains an x, it is considered a function of x. If it also contains a y, its items are placed in an anonymous function of y. If it also contains a z, its items are placed in an anonymous function of z.
 * Each named thing has its anonymous functions and if-statements identified.
 * The named things are put into an executable.

Afterwards, M is printed.