Misty Programming Language:


The Misty Language provides several object types.


literal array_literal function_literal logical_literal null_literal number_literal pattern_literal record_literal text_literal

A literal value can be an array literal, a logical literal, a function literal, a null literal, a number literal, a pattern literal, a record literal, or a text literal.


An array is an ordered collection of values. The values stored in an array can be of any type or mixture of types. Arrays are one dimensional. The first element of an array has an ordinal of 0. The length of an array is 1 plus the ordinal of the last element. The length can be obtained by the length function. Arrays of arrays can be used to simulate two dimensional arrays, and arrays of arrays of arrays can be used to simulate three dimensional arrays.

When an array is created, it is mutable or antestone. An array can be made immutable by the stone operator. Arrays are always passed by reference.

There two ways to make a new array: array literals and the array function.

Array literals

array_literal '[' array_filling ']'

array_filling "" elements indent open_elements outdent

elements spreadable_expression spreadable_expression ',' space elements

open_elements spreadable_expression spreadable_expression ',' space open_elements spreadable_expression linebreak open_elements

An array can be made from zero or more expressions, separated by commas, enclosed in brackets. Each expression produces a value of any type that is stored in the next element of the new array. The length of the array is the number of expressions. In closed form, the expressions are separated by commas and spaces. In open form, the expressions are separated by end of line and indentation.


var stooges: ["Curly", "Larry", "Moe"]
length(stooges)    # 3
var bears: [
length(bears)      # 3
var empty: []
length(empty)      # 0


The elements of an array are accessed using the bracket postfix notation.


The ordinal is an expression that produces a non-negative integer. When getting from an array, if the ordinal is not an integer, or if it is less than 0 or greater than or equal to the array's length then it produces null. When storing into an array, if the ordinal is not an integer, or if it is less than 0 or greater than or equal to the array's length then the operation fails. The number of elements in an array can be obtained by the length function.

If the array has multiple dimensions, additional subscripts can be used to specify a particular element.



set my_stooge: stooges[0]    # my_stooge is "Curly"
set stooges[0]: "Shemp"      # stooges is ["Shemp", "Larry", "Moe"]

The dot notation can not be used with arrays except to invoke the built-in array methods.

New elements can be appended to an array by assigning to the appendix. The appendix is written as empty brackets that signify the next potential element in the array. Reading from the appendix (which is only allowed in the set statement) removes the last element from an array.


set stooges[]: "Joe"       # stooges is ["Shemp", "Larry", "Moe", "Joe"]
set dropped: stooges[]     # dropped is "Joe"
set stooges[]: "Curly Joe" # stooges is ["Shemp", "Larry", "Moe", "Curly Joe"]


A blob is a container of bits. Blobs are usually used to represent things external to the Misty system, such as keys, network packets and images. Blobs can be acted upon with the blob functions.

The blob type does not have a literal.


logical_literal "false" "true"

There are two logical values: false and true. They are produced by the comparison operators, and are used by if statements and ternary expressions.


null_literal "null"

The null value is an empty immutable object. All attempts to obtain a value from null by refinement will produce null.

Any attempt to modify null will fail. Any attempt to invoke null will fail.

null is the value of uninitialized variables, missing parameters, missing fields in records, and invalid numbers. The |default operator can detect the presence of null and substitute another value.

null is the value of invalid numbers. For example, 1 / 0 is null.


Misty has a single number type: DEC64. Numbers can be as enormous as 3.6028797018963967e143 or as miniscule as 1.0e-127.

Numbers are immutable.

The null value is used to represent number values that can not be represented. This includes numbers that are 3.6028797018963968e143 or more, the result of division of non-zero by zero, type errors, and format errors. Any arithmetic operation in which one of the operands is not a number produces null as a result.

Numbers that are signed integers that can be represented exactly in 56 bits are called fit numbers.

Number literals

number_literal zero optional_frac int optional_frac optional_exp '-' zero frac '-' int optional_frac optional_exp

zero '0'

int one_nine more_digits

digits digit more_digits

more_digits "" '_' digits digits

one_nine '1' . '9'

digit zero one_nine

optional_frac "" frac

frac '.' digits

optional_exp "" 'e' digit 'e' digit digit "e1" digit digit "e-" digit "e-" digit digit "e-1" digit digit

Number literals are always in base 10. (See the number function to handle input in other bases.) A number literal is an optional -minus sign, one or more digits, an optional a single .decimal point followed by one or more digits, and an optional e and more digits indicating scientific notation. An _underbar in a number literal is ignored.



Misty is an object-oriented language but it is not a classical language: Objects are not rigidly defined by classes. Instead, Misty's records can be soft and malleable. Misty unifies traditional records and associative data structures. Records are unordered containers of key/value fields. Misty records can have fields added or removed at any time. Records are initially mutable, but can be made immutable by the stone statement. Fields can be accessed using either dot notation or bracket notation.

Record Literal

A new record can be made with a record literal.

record_literal '{' record_filling '}'

record_filling "" fields indent open_fields outdent

fields field field ',' space fields

open_fields field field linebreak open_fields

field name name ':' space expression text ':' space expression

In the record literal notation, the specification of a record begins with {left brace and ends with }right brace. Between them are zero or more name/value fields, separated by ,comma. A name/value field is an identifier or text, followed by :colon followed by an expression. (See JSON.) Each field contributes a field to the record.

If no value is supplied, then the value is obtained from a variable with the same name.

An empty record can be made by {}braces.

def empty_record: {}    # empty_record is {}

The statement:

def stooge: {first: "Curly", last: "Howard"}

has the same result as

def stooge: {
    first: "Curly"
    last: "Howard"


def stooge: {}
set stooge.first: "Curly"
set stooge.last: "Howard"

There is a special form of field that is a shorthand for creating a property with the same name as a variable that is initialized by the variable.

def color: {

def color: {
    "aliceblue": aliceblue
    "antiquewhite": antiquewhite
    "aqua": aqua


Keys can be

An invalid key type yields null on reading, and a failure on writing.

Keys in a record are unique. Writing a duplicate key first erases the original.

A key can not be a number, although a number converted to a text is allowed.

Stone record keys can only be made with a set statement. Record literals do not permit stone record keys.


The fields of a record can be accessed with either the dot notation or the subscript notation.

The dot notation is usually the most convenient notation for accessing the fields of a record. It takes a record, a .period, and an identifier. The dot notation is only allowed when the key is a text that conforms to the rules of a valid identifier. A key "a" (lower case) is distinct from a key "A" (upper case).


var stooge: {first: "Curly", last: "Howard"}
var first_name: stooge.first       # first_name is "Curly"
set first_name: null.first         # first_name is null
set new_stooge: record stooge
set new_stooge.first: "Shemp"      # new_stooge is {first: "Shemp"}
set last_name: new_stooge.last     # last_name is "Howard"

The subscript notation is similar to the dot notation, but instead of taking an identifier (which is used as a text) it can take an expression that produces a valid key. It can be used for dynamically making field names, or for creating keys that are not texts, such as stone records and stone arrays.

The subscript expression is wrapped in [left bracket and ]right bracket.


def stooge: {first: "Curly", last: "Howard"}
set first_name: stooge["first"]           # first_name is "Curly"
set stooge[null]: "Mogo on the Gogogo"    # fail


A field can be deleted by replacing its value with null.

set stooge.first: null


The method invocation pattern is


The record is searched for a field matching the method_name. If the result of that search is not a function, then it fails. There is no this or self binding.


A text is a sequence of zero or more 32-bit characters. Texts are immutable. It is not possible to alter a text, but it is very easy to construct new texts. There is no separate character type. A character is represented as a text with a length of 1.

Texts are concatenated with the ~tilde operator or the double tilde operator. The length function is used to determine the number of characters in a text.

Text literals

text_literal double chevron

double '""' '"' dchars '"'

dchars dchar dchar dchars

dchar '0020' . '10ffff' - '"' - '\' '\' escape

escape 'b' 'd' 'g' 'n' 'q' 'r' 't' "u{" hexes '}'

hexes hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex hex

hex '0' . '9' 'A' . 'F'

\b \backslash
\d »droite
\g «gauche
\n  linefeed
\q "double quote
\r  carriage_return
\t  tab

A text literal is bounded by a pair of "double quote. Between the quotes are zero or more characters and escape sequences. The escape sequences are a \reverse solidus followed by 1 to 11 additional characters. Each escape sequence contributes a single character to the text. The \u{HHHHHHHH} sequence uses one to eight base-16 digits to represent any 32 bit character.

The table shows all of the legal escape sequences. If \reverse solidus does not form an escape sequence, then there is a syntax error.

A text must begin and end on the same line. Control characters are not permitted in text literals.

"This is a text."

"So is this."

""    # an empty text

"\u{0043}\u{0061}\u{0074}"    # "Cat"

"This text contains \qquotes\q."

"This is \
an error."        # must begin and end on the same line

A text can not contain a literal control character, but control characters can be embedded in texts with escape sequences.

"This is not\nan error."

"Neither is\u{A}this."

Chevron text literals

chevron '«' cchars '»'

cchars "" chevron cchars cchar cchars

cchar '0009' '000A' '000D' '0020' . '10FFFF' - '«' - '»'

A text literal can also be bounded by «left-pointing double angle quotation mark (U+00AB) and »right-pointing double angle quotation mark (U+00BB). (Note that the « is distinct from < and <<<.) These text literals contain no escape sequences; \reverse solidus is treated as an ordinary character. The chevron quote characters can be nested literally within a chevron text as long as they are properly balanced. The control characters tab, carriage_return, and linefeed, are permitted.

«This text
takes up
three lines.»

««««Chevrons may be nested when «properly» balanced»»»»

«Now it isn't necessary to escape "double quotes".»

«file:c:\nt\autoexec.bat»    # same as "file:c:\bnt\bautoexec.bat"

«The chorus entered, said «France hath in thee found out
A nest of hollow bosoms, which he fills
With treacherous crowns», and then exited.»


Subscripting can be used to access the individual characters of a text. Subscripts are integers that are greater than or equal to zero and less than the length of the text. Texts are immutable, so subscripts can not be used to change a character within a text.

var my_text: "cat"
length(my_text)       # 3
my_text[0]            # "c"
my_text[2]            # "t"
my_text[4]            # ""
set my_text[0]: "r"   # fail