NRPL specification

2016-11-11

NRPL is a stack-based language heavily inspired by Hewlett-Packard’s RPL (from which it derives its name) and Forth. It is intended to be easy to parse (it has no grammar) and relatively cheap to process.

Introduction

A program consists of a list of words, which are processed and the result is pushed into a stack. Results are pushed to the “bottom” of the stack, and arguments, when required, are taken from there, starting with the bottommost value. There are also various stack manipulation commands.

Words are processed from left to right, each word taking arguments and depositing results as needed from the stack.

The following example code adds 3 + 5: 3 5 +. At the end of execution, the stack consists of the value 8.

Data Types

Strings

A string is any sequence of characters enclosed in double quotes. The double quote character itself is not permitted within a string.

Examples:

Numbers

A number is any sequence of digits, optionally preceded by a + or a - sign, and optionally containing a decimal point.

Examples:

Numbers are initially parsed as floating point, but may be treated as integers, booleans, or even strings depending on the context.

Timestamps

Timestamps are expressions enclosed in @ characters. A variety of expressions are supported but whenever possible, it’s best to stick to a well-defined convention such as ISO-8601.

Examples:

Arrays

Arrays are ordered collections of elements. They cannot be entered directly as literals, but must be created, e.g., via the →LIST command. See the arrays and objects section below.

Examples:

Sets

Sets are unordered collections of unique elements. They cannot be entered directly as literals, but must be created, e.g., via the NEWSET command. See the set operations section below.

Examples:

Objects

Objects are unordered collections of properties, each consisting of a name (or key) and a value. Objects cannot be entered directly as literals, but must be created, e.g., via the OBJECT command. See the arrays and objects section below.

Examples:

Code literals

Code literals are sequences of words which are not evaluated immediately, but are pushed into the stack and treated like any other object. They can be evaluated latter, either explicitly via the EVAL command or implicitly by certain operations such as IFT and IFTE.

Literals are enclosed in « and » character pairs. Literals can contain other literals up to five levels deep.

Examples:

Comments

Comments can be included in the code by starting them with a § (paragraph) sign.

Comments run either until the next § sign or until the end of the line or the end of the expression, whichever comes first.

Additionally, if the first (and only the first) line of an expression starts with a hashbang (#!), that line will be removed before the expression is evaluated.

Examples:

Variables

The language supports two types of variables, local and external, and two type of operation on each: assignment and recall. Whether all of those types and operations are available to the user, however, depends on where the language is being used, as those features can be enabled or disabled independently.

Variable names are case-sensitive and may consist of the characters A-Z, a-z, 0-9, and the underscore.

External variables

External variables are one of the ways in which the language communicates with its external environment. For example, if the language is being used to process weather records, variables may represent various weather measurements such as temperature, humidity, etc. This is entirely dependent on the implementation.

External variable assignment

If permitted, values may be assigned to external variables by preceding their name with an exclamation mark.

Example:

If assignment is not permitted, the variable expression will be silently discarded.

External variable recall

Values from external variables can be recalled (pushed to the bottom of the stack) by preceding their name with a dollar sign.

Example:

If external variable recall is not enabled, the variable expression will be silently discarded.

Local variables

Local variables may be used to store temporary results, especially those that will be reused multiple times during the evaluation of an NRPL program.

Unlike external variables which may be disabled, read-only, or read-write, local variables may be either disabled or read-write.

Local variable assignment

Locals use two exclamation marks instead of one.

Examples:

Local variable recall

Two dollar signs precede a local variable name.

Example:

Code literals and local variables

As a special case, if a code literal is stored in a local variable, when the variable is recalled, the code will be automatically evaluated.

Example:

«
1 * § Coerce to a number whatever is on stack level 1
1 + § And increment it by one
» !!INCR § Save in the (case-sensitive) local variable INCR
6
$$INCR § Should return 7

To recall the unevaluated contents of a code literal local variable, you may use the LOCAL and GET commands:

"INCR"
LOCAL
GET § Should return the actual code literal

Commands

In general, commands take their arguments from the bottom of the stack and push their results also to the bottom. Commands may return multiple values, or none at all.

Constants

Pi

Returns an approximation of Pi (3.14159…)

Command(s):

pi, 𝜋, 𝛑

Note: The ‘𝜋’ alias is Unicode character U+1D70B (MATHEMATICAL ITALIC SMALL PI),
and the ‘𝛑’ alias is Unicode character U+1D6D1 (MATHEMATICAL BOLD SMALL PI).
Unicode character U+03C0 π (GREEK SMALL LETTER PI) is not used in order to
respect the principle that commands are case-insensitive and avoid ambiguity
with the PROD operator.

Arguments:
(none)

Output:

1: {Number}

Base of natural logarithms

Returns an approximation of ‘e’ (2.718…)

Command(s):

e

Arguments:
(none)

Output:

1: {Number}

Arithmetic operations

Addition

Adds the numbers in the first two levels of the stack.

Command(s):

+, ADD

Arguments:

2: {Number}
1: {Number}

Output:

1: {Number}

Example:

Code:

5 3 +

Result:

8

Subtraction

Subtracts the number on stack level 1 from the number on stack level 2.

Command(s):

-

Arguments:

2: {Number}
1: {Number}

Output:

1: {Number}

Example:

Code:

5 3 -

Result:

2

Multiplication

Multiplies the numbers in the first two levels of the stack

Command(s):

*, ×

Arguments:

2: {Number}
1: {Number}

Output:

1: {Number}

Example:

Code:

5 3 *

Result:

15

Division

Divides the number on stack level 2 by the number on stack level 1.

Command(s):

/, ÷

Arguments:

2: {Number}
1: {Number}

Output:

1: {Number}

Example:

Code:

5 3 /

Result:

1.6666666666666667

Invert sign

Inverts the sign of the number on stack level 1 (equivalent to multiplying by -1).

Command(s):

INV, ±

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

3 ±

Result:

-3

Absolute value

Returns the absolute value of the number on stack level 1.

Command(s):

ABS

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

-5 ABS 3 ABS

Result:

5
3

Remainder

Gets the remainder of the division of the number in stack level 2 by the number on stack level 1.

Command(s):

REM

Arguments:

2: {Number}
1: {Number}

Output:

1: {Number}

Example:

Code:

5 3 REM -76 21 REM

Result:

2
-13

Exponentiation

Raises the number in stack level 2 to the power of the number in stack level 1.

Command(s):

POW, ^

Arguments:

2: {Number}
1: {Number}

Output:

1: {Number}

Example:

Code:

5 3 POW

Result:

125

Square root

Takes the square root of the number in stack level 1.

Command(s):

SQRT,

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

9 SQRT

Result:

3

Square

Raises the number on stack level 1 to the power of 2.

Command(s):

SQ, ²

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

3 SQ -7²

Result:

9
49

Natural logarithm

Returns the natural logarithm (base e) of the number in stack level 1.

Command(s):

LN

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

1 LN

Result:

0

Base 10 logarithm

Returns the base 10 logarithm of the number in stack level 1.

Command(s):

LOG

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

10 LOG

Result:

1

Rounding

Rounds the number on stack level 2 to the number of decimals on stack level 1, which must be between 0 and 20, and converts it to a string.

Command(s):

TOFIXED, →FIX

Arguments:

2: {Number}
1: {Number}

Output:

1: {String}

You may use 1 * to convert the result back to a number.

Example:

Code:

5 3 / 2 TOFIXED

Result:

"1.67"

Trigonometric operations

Sine

Returns the sine of the angle, in radians, in stack level 1.

Command(s):

SIN

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

PI 2 / SIN

Result:

1

Cosine

Returns the cosine of the angle, in radians, in stack level 1.

Command(s):

COS

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

PI COS

Result:

-1

Tangent

Returns the tangent of the angle, in radians, in stack level 1.

Command(s):

TAN

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

0 TAN

Result:

0

Arc sine

Returns the arc sine, in radians, of the number in stack level 1.

Command(s):

ASIN

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

1 ASIN

Result:

1.5707963267948966

Arc cosine

Returns the arc cosine, in radians, of the number in stack level 1.

Command(s):

ACOS

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

1 ACOS

Result:

0

Arc tangent

Returns the arc tangent, in radians, of the number in stack level 1.

Command(s):

ATAN

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

1 0 / ATAN

Result:

1.5707963267948966

Arc tangent (quotient)

Returns the arc tangent, in radians, of the number in stack level 1 divided by the number in stack level 2.

Command(s):

ATAN

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

0 1 ATAN2

Result:

1.5707963267948966

Hyperbolic sine

Returns the hyperbolic sine of the number in stack level 1.

Command(s):

SINH

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

1 5 SQRT + 2/ LN SINH

Result:

0.5

Hyperbolic cosine

Returns the hyperbolic cosine of the number in stack level 1.

Command(s):

COSH

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

0 COSH

Result:

1

Hyperbolic tangent

Returns the hyperbolic tangent of the number in stack level 1.

Command(s):

TANH

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

0 TANH

Result:

0

Hyperbolic arcsine

Returns the hyperbolic arcsine of the number in stack level 1.

Command(s):

ASINH

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

e 0.5 ASINH ^ 2 * 1 - SQ

Result:

5

Hyperbolic arccosine

Returns the hyperbolic arccosine of the number in stack level 1.

Command(s):

ACOSH

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

1 ACOSH

Result:

0

Hyperbolic arctangent

Returns the hyperbolic arctangent of the number in stack level 1.

Command(s):

ATANH

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

0 ATANH

Result:

0

Hypothenuse

Returns the the square root of the sum of the squares of the numbers in stack level 1 and stack level 2.

Command(s):

HYPOTHENUSE, HYPOT

Arguments:

2: {Number}
1: {Number}

Output:

1: {Number}

Example:

Code:

3 4 HYPOT

Result:

5

Conversion

Radians to degrees

Converts the number in stack level 1 from radians to degrees

Command(s):

R→D

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

PI R→D

Result:

180

Degrees to radians

Converts the number in stack level 1 from degrees to radians.

Command(s):

D→R

Arguments:

1: {Number}

Output:

1: {Number}

Example:

Code:

180 D→R

Result:

3.141592653589793

Comparison

Equality

Compares the values in the first two stack levels. Returns TRUE if equal, FALSE otherwise.

Command(s):

EQ, =

Arguments:

2: {Number|String|Boolean}
1: {Number|String|Boolean}

Output:

1: {Boolean}

Example:

Code:

5 3 =
"ab" "ab" =

Result:

FALSE
TRUE

Inequality

Compares the values in the first two stack levels. Returns FALSE if equal, TRUE otherwise.

Command(s):

NE,

Arguments:

2: {Number|String|Boolean}
1: {Number|String|Boolean}

Output:

1: {Boolean}

Example:

Code:

5 3 ≠
"ab" "AB" NE

Result:

TRUE
TRUE

Less-than

Compares the values in the first two stack levels. Returns TRUE if the value on level 2 is less than the value on level 1, FALSE otherwise.

Command(s):

LT, <

Arguments:

2: {Number|String|Boolean}
1: {Number|String|Boolean}

Output:

1: {Boolean}

Example:

Code:

5 3 <
"ab" "ac" <
FALSE TRUE LT

Result:

FALSE
TRUE
TRUE

Greater-than

Compares the values in the first two stack levels. Returns TRUE if the value on level 2 is greater than the value on level 1, FALSE otherwise.

Command(s):

GT, >

Arguments:

2: {Number|String|Boolean}
1: {Number|String|Boolean}

Output:

1: {Boolean}

Example:

Code:

5 3 GT
"ab" "ac" >
FALSE TRUE >

Result:

TRUE
FALSE
FALSE

Less-than or equal

Compares the values in the first two stack levels. Returns TRUE if the value on level 2 is less than or equal to the value on level 1, FALSE otherwise.

Command(s):

LE,

Arguments:

2: {Number|String|Boolean}
1: {Number|String|Boolean}

Output:

1: {Boolean}

Example:

Code:

5 3 ≤
"ab" "ac" LE
FALSE TRUE LE
7 7 ≤

Result:

FALSE
TRUE
TRUE
TRUE

Greater-than or equal

Compares the values in the first two stack levels. Returns TRUE if the value on level 2 is greater than or equal to the value on level 1, FALSE otherwise.

Command(s):

GE,

Arguments:

2: {Number|String|Boolean}
1: {Number|String|Boolean}

Output:

1: {Boolean}

Example:

Code:

5 3 GE
"ab" "ac" ≥
FALSE TRUE ≥
7 7 ≥

Result:

TRUE
FALSE
FALSE
TRUE

Logic operations

AND

Applies the JavaScript AND (&&) operation to the values in the first two stack levels.

Note that the operation will be shortcut if the value in stack level 1 is falsey, as seen in the examples below.

Command(s):

AND,

Arguments:

2: {Any}
1: {Any}

Output:

1: {Boolean}

Example:

Code:

5 3 AND
TRUE TRUE AND
"" "ab" AND
0 3 AND
"ac" « 5 3 + » AND

Result:

5
TRUE
""
0
"ac"

OR

Applies the JavaScript OR (||) operation to the values in the first two stack levels.

Note that the operation will be shortcut if the value in stack level 1 is truthy, as seen in the examples below.

Command(s):

OR,

Arguments:

2: {Any}
1: {Any}

Output:

1: {Boolean}

Example:

Code:

5 3 OR
TRUE TRUE OR
"" "ab" OR
0 3 OR
"ac" « 5 3 + » OR

Result:

3
TRUE
"ab"
3
« 5 3 + »

XOR

Applies a logical exclusive OR operation to the values in the first two stack levels. Returns TRUE if exactly one of them is truthy, FALSE otherwise.

Command(s):

XOR, ,

Arguments:

2: {Any}
1: {Any}

Output:

1: {Boolean}

Example:

Code:

5 3 XOR
TRUE TRUE XOR
"" "ab" XOR
0 3 XOR
"ac" « 5 3 + » XOR

Result:

FALSE
FALSE
TRUE
TRUE
FALSE

NOT

Negates the value in the first level of the stack. Returns TRUE if the value is falsey, FALSE if it’s truthy.

Command(s):

NOT, ¬

Arguments:

2: {Any}
1: {Any}

Output:

1: {Boolean}

Example:

Code:

"ac" NOT « 5 3 + » NOT 0 NOT 5 NOT

Result:

FALSE
FALSE
TRUE
FALSE

True

Pushes the boolean value TRUE onto the stack.

Command(s):

TRUE

Arguments:

(none)

Output:

1: {Boolean}

Example:

Code:

TRUE

Result:

TRUE

False

Pushes the boolean value FALSE onto the stack.

Command(s):

FALSE

Arguments:

(none)

Output:

1: {Boolean}

Example:

Code:

FALSE

Result:

FALSE

String operations

Concatenation

Concatenates the strings in the first two levels of the stack. If only one element is a string, the other will be coerced into one.

Command(s):

+, ADD

Arguments:

2: {String}
1: {String}
2: {String}
1: {Any}
2: {Any}
1: {String}

Output:

1: {String}

Example:

Code:

"a" "b" +

Result:

"ab"

Lowercase

Convert string to lowercase. If the object in level 1 of the stack is not a string, it will be coerced into one.

Command(s):

LOWER

Arguments:

1: {String}
1: {Any}

Output:

1: {String}

Example:

Code:

"Hello" LOWER

Result:

"hello"

Uppercase

Convert string to uppercase. If the object in level 1 of the stack is not a string, it will be coerced into one.

Command(s):

UPPER

Arguments:

1: {String}
1: {Any}

Output:

1: {String}

Example:

Code:

"Hello" UPPER

Result:

"HELLO"

Substring

Check if the string in stack level 1 contains within it the string in stack level 2. Coercion may apply.

Command(s):

SUBSTR

Arguments:

2: {String}
1: {String}

Output:

1: {Boolean}

Example:

Code:

"el" "Hello" SUBSTR

Result:

TRUE

Check if empty

Check if the string in stack level 1 is empty. Coercion may apply.

Command(s):

EMPTY

Arguments:

2: {String}
1: {String}

Output:

1: {Boolean}

Example:

Code:

"Hello" EMPTY "" EMPTY

Result:

FALSE
TRUE

Regular expressions

Create regular expression

Takes a string from stack level 1 and converts it to a regular expression object. If the object in stack level 1 is an array, its first member is used as the regular expression and its second member is used as flags to be passed to the RegExp constructor.

Command(s):

REGEXP

Arguments:

1: {String|Array}

Output:

1: {RegExp}

Example:

Code:

"^Ba.*t$" REGEXP

Result:

/^Ba.*t$/

Test regular expression

Takes a string from stack level 2 and tests it against the regular expression in stack level 1. Returns TRUE if it matches, FALSE otherwise.

Command(s):

RXTEST

Arguments:

2: {String}
1: {RegExp}

Output:

1: {Boolean}

Example:

Code:

"^Ba.*t$" "i" 2 →LIST REGEXP !!rx
"ballet" $$rx RXTEST
"Basket" $$rx RXTEST
"Baile" $$rx RXTEST

Result:

TRUE
TRUE
FALSE

Match regular expression

Takes a string from stack level 2 and matches it against the regular expression in stack level 1. If matches occur, returns an array where the first element is the matched substring, and the rest are the parenthesised capture expressions, if any. In case of no matches, returns null.

Command(s):

RXEXEC

Arguments:

2: {String}
1: {RegExp}

Output:

1: {Array|null}

Example:

Code:

"([\\w]+):(.+)" REGEXP !!rx
"number:5" $$rx RXEXEC
"this is a key:value" $$rx RXEXEC
"nothing" $$rx RXEXEC

Result:

[ 'number:5', 'number', '5' ]
[ 'key:value', 'key', 'value' ]
null

Date and time operations

Convert to local timestamp

Command(s):

Convert the string or number in stack level 1 to a local timestamp. If a number, it should be milliseconds since the UNIX epoch.

ASDATETIME

Arguments:

1: {String|Number}

Output:

1: {Timestamp}

Example:

Code:

"2016-01-01T15:00" ASDATETIME
@2016-01-01T14:00@
-

Result:

3600000

Convert to UTC timestamp

Convert the string or number in stack level 1 to a UTC timestamp. If a number, it should be milliseconds since the UNIX epoch.

Command(s):

UTC

Arguments:

1: {String|Number}

Output:

1: {Timestamp}

Example:

Code:

"2016-06-01T15:00" UTC
"2016-06-01T15:00+0200" ASDATETIME -

Result:

7200000

Get UNIX epoch (milliseconds)

Get the number of milliseconds since the UNIX epoch, in milliseconds, for a given timestamp.

Command(s):

UNIXOFFSET

Arguments:

1: {Timestamp}

Output:

1: {Number}

Example:

Code:

"2016-06-01T15:00" UTC
UNIXOFFSET

Result:

1464793200000

Convert to/from UNIX epoch (seconds)

If the object in stack level 1 is a timestamp, return the corresponding number of seconds since the UNIX epoch, in seconds. If the object in stack level 1 is a number, return the timestamp corresponding to that UNIX epoch.

Command(s):

UNIX

Arguments:

1: {Timestamp|Number}

Output:

1: {Number|Timestamp}

Example:

Code:

"2016-06-01T15:00" UTC
UNIX
DUP
UNIX ISO8601

Result:

1464793200, '2016-06-01T15:00:00.000Z'

Get current date/time

Return the current UTC timestamp.

Command(s):

NOW

Arguments:

(none)

Output:

1: {Timestamp}

Example:

Code:

NOW ISO8601

Result:

"2016-01-01T20:31:34.897Z"

Format timestamp

Format the timestamp in stack level 1 according to the format string given in stack level 2, and return a string.

The underlying code uses Moment.js for the conversion, refer to the Moment manual for format details.

Command(s):

DTFORMAT

Arguments:

2: {String}
1: {Timestamp}

Output:

1: {String}

Example:

Code:

"2016-06-01T15:00" UTC
UNIX
DUP
UNIX ISO8601

Result:

1464793200, '2016-06-01T15:00:00.000Z'

Stack manipulation

Clear stack

Removes all objects from the stack.

Command(s):

CLEAR

Arguments:

n: {Any}ⁿ

2: {Any}²
1: {Any}¹

Output:

n:

2:
1:

Drop object

Removes the object on the first level of the stack.

Command(s):

DROP,

Arguments:

1: {Any}

Output:

1:

Duplicate object

Makes a copy of the object in level 1 of the stack.

Command(s):

DUP,

Arguments:

1: {Any}

Output:

2: {Any}
1: {Any}

Swap objects

Interchanges the first two objects on the stack.

Command(s):

SWAP

Arguments:

2: {Any}²
1: {Any}¹

Output:

2: {Any}¹
1: {Any}²

Rotate objects

Rotates the first three objects on the stack, moving the object in level 3 to level 1.

This command is equivalent to 3 ROLL.

Command(s):

ROT

Arguments:

3: {Any}³
2: {Any}²
1: {Any}¹

Output:

3: {Any}²
2: {Any}¹
1: {Any}³

Roll objects

Moves the contents of a specified level of the stack to level 1, and rolls upwards the portion of the stack beneath the specified level.

Command(s):

ROLL

Arguments:

n: {Any}ⁿ⁻¹

1: {Any}¹
1: {Number} n

Output:

n: {Any}ⁿ⁻²

2: {Any}¹
1: {Any}ⁿ

Inverse roll objects

Moves the contents of level 1 to a specified level, and rolls downwards the portion of the stack beneath the specified level.

Command(s):

ROLLD

Arguments:

n: {Any}ⁿ⁻¹

1: {Any}¹
1: {Number} n

Output:

n: {Any}¹

2: {Any}³
1: {Any}²

Pick object

Copies the contents of a specified level to level 1.

Command(s):

PICK

Arguments:

n: {Any}ⁿ

2: {Any}²
1: {Any}¹

Output:

n: {Any}ⁿ⁻¹

2: {Any}¹
1: {Any}ⁿ

Copy object

Returns a copy to stack level 1 of the object in level 2.

Command(s):

OVER

Arguments:

2: {Any}²
1: {Any}¹

Output:

3: {Any}²
2: {Any}¹
1: {Any}²

Stack depth

Returns the number of objects in the stack, prior to executing this command.

Command(s):

DEPTH

Arguments:

(none)

Output:

1: {Number}

Array and object operations

Get element

Gets an element from an array or a property from an object.

Command(s):

GET

Arguments:

2: {Number|String}
1: {Array|Object}

Output:

1: {Any}

Set element

Replaces (or inserts) an element at a given index of an array, or sets a given property on an object.

Command(s):

SET

Arguments:

3: {Any}
2: {Number|String}
1: {Array|Object}

Output:

1: {Array}

Example:

Code:

"x" 2 "a" "b" "c" "d" "e" 5 →LIST SET

Result:

[ "a", "b", "x", "d", "e" ]

Accessors

Lists can be accessed via the CAR and CDR expressions, borrowed from Lisp. CADRs can be combined up to seven levels deep.

Command(s):

CAR, CDR, CAAR, CADR, CDAR, CDDR, etc.

Arguments:

1: {Array|String}

Output:

1: {Any}

Example:

Code:

"Monday" "Tuesday" "Wednesday" "Thursday" "Friday" 5 →LIST DUP
CAR OVER CDR ROT CDDDADDR

Result:

"Monday"
[ "Tuesday", "Wednesday", "Thursday", "Friday" ]
"nesday"

Create object

Puts an empty object on stack level 1.

Command(s):

OBJECT

Arguments:

(none)

Output:

1: {Object}

Create array

Puts an empty array on stack level 1.

Command(s):

ARRAY, LIST

Arguments:

(none)

Output:

1: {Array}

Collect into array

Given a number n, takes the elements from stack level n+1 to stack level 1 and collects them in an array.

Alternatively, given a set in stack level 1, converts it to an array.

Command(s):

→LIST, >LIST

Arguments:

n: {Any}ⁿ⁻¹

3: {Any}²
2: {Any}¹
1: {Number} n

Output:

1: {Array}

Arguments:

1: {Set}

Output:

1: {Array}

Example:

Code:

"a" "b" "c" "d" "e" 3 →LIST

Result:

"a"
"b"
[ "c", "d", "e" ]

Explode array

Given an array in stack level 1, pushes each of its elements to the stack, and returns the number of elements.

Command(s):

LIST→, LIST>

Arguments:

1: {Array}

Output:

n: {Any}

2: {Any}
1: {Number}

Sort array

Sorts the items of the array on stack level 1.

For numeric items, the sort is numeric. For anything else, a string comparison is done.

Command(s):

SORT

Arguments:

1: {Array}

Output:

1: {Array}

Reverse array

Reverses the order of the items of the array on stack level 1.

Command(s):

REVERSE

Arguments:

1: {Array}

Output:

1: {Array}

Get array length

Given an array on stack level 1, returns the number of its elements.

Command(s):

COUNT

Arguments:

1: {Array}

Output:

1: {Number}

Array index

Returns the index of the first occurrence of the element on stack level 2 in the array on stack level 1, or -1 if the element is not present.

Command(s):

INDEXOF

Arguments:

2: {Any}
1: {Array}

Output:

1: {Number}

Get maximum value

Given a numeric array on stack level 1, returns its maximum value.

Command(s):

MAX

Arguments:

1: {Array<Number>}

Output:

1: {Number}

Get minimum value

Given a numeric array on stack level 1, returns its minimum value.

Command(s):

MIN

Arguments:

1: {Array<Number>}

Output:

1: {Number}

Sum elements

Given a numeric array on stack level 1, returns the sum of its elements.

Command(s):

SUM,

Note: The ‘∑’ alias is Unicode character U+2211 (N-ARY SUMMATION), and
not Unicode character U+03A3 Σ (GREEK CAPITAL LETTER SIGMA), which is
not used in order to respect the principle that commands are case-insensitive.

Arguments:

1: {Array<Number>}

Output:

1: {Number}

Multiply elements

Given a numeric array on stack level 1, returns the product of its elements.

Command(s):

PROD,

Note: The ‘∏’ alias is Unicode character U+220F (N-ARY PRODUCT), and
not Unicode character U+03A0 Π (GREEK CAPITAL LETTER PI), which is
not used in order to respect the principle that commands are case-insensitive
and avoid ambiguity with the Pi constant.

Arguments:

1: {Array<Number>}

Output:

1: {Number}

Filter array of objects by property

Given an array consisting of objects and a property name, return an array containing only the object that have the given property.

Command(s):

EACH

Arguments:

2: {Array<Object>}
1: {String}

Output:

1: {Array<Object>}

Local variables object

Pushes into the stack an object containing a reference to all the local variables that have been defined.

If no local variables were defined or they were disabled when initialising the NRPL engine, returns an empty object.

Command(s):

LOCAL

Arguments:

(none)

Output:

1: {Object}

Set operations

New set

Creates an empty set in stack level 1.

Command(s):

NEWSET,

Arguments:

(none)

Output:

1: {Set}

Example:

Code:

NEWSET

Result:

{}

Clear set

Removes all elements from the set in stack level 1.

Command(s):

CLEARSET

Arguments:

1: {Set}

Output:

1: {Set}

Example:

Code:

1 2 3 3 →SET CLEARSET

Result:

{}

Create set

Given a number n, takes the elements from stack level n+1 to stack level 1 and collects them in a set (removing duplicates).

Alternatively, given an array in stack level 1, converts it to a set.

Command(s):

→SET

Arguments:

n: {Any}ⁿ⁻¹

3: {Any}²
2: {Any}¹
1: {Number} n

Output:

1: {Set}

Arguments:

1: {Array}

Output:

1: {Set}

Example:

Code:

"a" "b" "c" "d" "e" 3 →SET

Result:

"a"
"b"
{ "c", "d", "e" }

Explode set

Given a set in stack level 1, pushes each of its elements to the stack, and returns the number of elements.

Command(s):

SET→

Note: LIST→ has the same effect.

Arguments:

1: {Set}

Output:

n: {Any}

2: {Any}
1: {Number}

Set union

Returns the union of the sets in the first two stack levels.

If any of the elements are not sets, they will be coerced to a set. For arrays, the array is converted to a set as if the →SET operation had been called. For other elements, they are replaced with a set having that element as its single member.

Command(s):

SUNION, ,

Arguments:

2: {Any}
1: {Any}

Output:

1: {Set}

Example:

Code:

"a" "b" ⋃
"b" "c" ⋃

Result:

{ "a", "b", "c" }

Set intersection

Returns the intersection of the sets in the first two stack levels.

If any of the elements are not sets, they will be coerced to a set. For arrays, the array is converted to a set as if the →SET operation had been called. For other elements, they are replaced with a set having that element as its single member.

Command(s):

SINTERSECT, ,

Arguments:

2: {Any}
1: {Any}

Output:

1: {Set}

Example:

Code:

"a" "b" ⋃
"b" "c" ⋃

Result:

{ "b" }

Set complement

Given a set A in stack level 2 and a set B in stack level 1, returns the set of elements in A which are not in B.

Command(s):

SMINUS, SCOMPLEMENT,

Arguments:

2: {Set}
1: {Set}

Output:

1: {Set}

Example:

Code:

"a" "b" ⋃
"b" "c" ⋃

Result:

{ "a" }

Set difference

Given a set A in stack level 2 and a set B in stack level 1, returns (AB) ⋃ (BA).

Command(s):

SDIFF,

Arguments:

2: {Set}
1: {Set}

Output:

1: {Set}

Example:

Code:

"a" "b" ⋃
"b" "c" ⋃

Result:

{ "a", "c" }

Set product

Given a set A in stack level 2 and a set B in stack level 1, returns a set containing all ordered pairs of the elements in A followed by the elements in B, i.e.,: ❴ (a, b)aA, bB ❵.

Command(s):

SPROD

Arguments:

2: {Set}
1: {Set}

Output:

1: {Set}

Example:

Code:

"a" "b" ⋃
"b" "c" ⋃
SPROD

Result:

{
[ "a", "b" ],
[ "a", "c" ],
[ "b", "b" ],
[ "b", "c" ]
}

Subset

Returns TRUE if the set in stack level 1 is a subset (or equal to) the set in stack level 2.

Command(s):

SUBSETOF, ,

Arguments:

2: {Set}
1: {Set}

Output:

1: {Boolean}

Example:

Code:

"a" "b" ⋃ "c" ⋃
"b" "c" ⋃

Result:

TRUE

Superset

Returns TRUE if the set in stack level 1 is a superset (or equal to) the set in stack level 2.

Command(s):

SUPERSETOF, ,

Arguments:

2: {Set}
1: {Set}

Output:

1: {Boolean}

Example:

Code:

"a" "b" ⋃ "c" ⋃
"b" "c" ⋃

Result:

FALSE

Membership

Returns TRUE if the set in stack level 1 contains the element in stack level 2.

Command(s):

ELEMENTOF, ,

The command may also be used, and is equivalent to ∈¬.

Arguments:

2: {Any}
1: {Set}

Output:

1: {Boolean}

Example:

Code:

"a"
"a" "b" ⋃

Result:

TRUE

Containment

Returns TRUE if the set in stack level 2 contains the element in stack level 1.

Command(s):

CONTAINS, ,

This command is equivalent to SWAP ∈.
The command may also be used, and is equivalent to ∋¬.

Arguments:

2: {Set}
1: {Any}

Output:

1: {Boolean}

Example:

Code:

"a" "b" ⋃
"a"

Result:

TRUE

Conditionals

The conditionals have two forms: a pure stack-based one and a FORTH alternative. Both are presented below.

If-then (stack-based)

This command takes two code literals, a condition from stack level 2 and an expression from stack level 1. If the condition evaluates to true, the expression is executed, else it is dropped.

Command(s):

IFT

Arguments:

2: {Code}
1: {Code}

Output:

(depends on the expression argument)

Example:

This code checks if the result of 5 + 3 is divisible by 2, and if so, it halves it.

Code:

5 3 +
« DUP 2 REM 0 EQ »
« 2 / »
IFT

Result:

4

If-then (FORTH-like)

Command(s):

<condition> IF <expression> THEN

Arguments:

1: {Boolean}

Output:

(depends on the expression argument)

Example:

This is the same example as above in FORTH notation.

Code:

5 3 +
DUP 2 REM 0 EQ
IF
2 /
THEN

Result:

4

If-then-else (stack-based)

This command takes three code literals, a condition from stack level 3, and an expression each from stack levels 2 and 1. If the condition evaluates to true, the expression from stack level 1 is executed, else the one from stack level 2.

Command(s):

IFTE

Arguments:

3: {Code}
2: {Code}
1: {Code}

Output:

(depends on the expression arguments)

Example:

This code checks if the result of 5 + 3 is odd, and if so, doubles it, otherwise halves it.

Code:

5 3 +
« DUP 2 REM 0 NE »
« 2 / »
« 2 * »
IFTE

Result:

16

If-then-else (FORTH-like)

Command(s):

<condition> IF <expression-if-false>> ELSE <expression-if-true> THEN

Arguments:

1: {Boolean}

Output:

(depends on the expression argument)

Example:

This is the same example as above in FORTH notation.

Code:

5 3 +
DUP 2 REM 0 NE
IF
2 /
ELSE
2 *
THEN

Result:

16

Loops

While

The “while” loop takes a condition from stack level 2 and an expression from stack level 1, and executes the expression while the condition evaluates to true.

Command(s):

WHILE

Arguments:

2: {Code}
1: {Code}

Output:

(depends on the expression argument)

Example:

This code repeatedly performs division by two on its argument as long as the result is evenly divisible.

Code:

24
« DUP 2 REM 0 EQ »
« 2 / DUP »
WHILE
DROP

Result:

12
6
3

Repeat

The “repeat” loop takes a number n from stack level 2 and an expression from stack level 1, and executes the expression n times.

Command(s):

REPEAT

Arguments:

2: {Number}
1: {Code}

Output:

(depends on the expression argument)

Example:

This code creates an array with the sequence 100, 110, 120, 130, 140, 150.

Code:

100
5
« DUP 10 + »
REPEAT
6 →LIST

Result:

[ 100, 110, 120, 130, 140, 150 ]