Misty Programming Language:

Types

The Misty Language provides several object types.

Literal

literal array_literal function_literal number_literal pattern_literal record_literal text_literal

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

Array

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.

Arrays are always passed by reference.

The assign statement is able to append values to an array (push) and remove values from the end of an array (pop).

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

Array literals

array_literal '[' array_filling ']'

array_filling "" expression elements indent expression open_elements outdent

elements "" ',' space expression elements

open_elements "" ',' space expression open_elements linebreak expression 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. The length of an array is fixed at its creation. In closed form, the expressions are separated by commas and spaces. In open form, the expressions are separated by end of line and indentation.

Example:

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

Subscripting

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

array[ordinal]

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 disrupts. 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.

array[ordinal0][ordinal1][ordinal2]

Example:

assign my_stooge: stooges[0]    # my_stooge is "Curly"
assign stooges[0]: "Shemp"      # stooges is ["Shemp", "Larry", "Moe"]
assign stooges[]: "Joe"         # stooges is ["Shemp", "Larry", "Moe", "Joe"]
assign popped: stooges[]        # stooges is ["Shemp", "Larry", "Moe"]
                                # popped is "Joe"

Blob

A blob is a container of bits. Blobs are usually used to represent things external to the Misty system, such as keys, network packets, sounds, and images.

See blob.

Number

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 '-' negative_number_literal unsigned_number_literal '0' zero

zero "" frac optional_exp

unsigned_number_literal int optional_frac optional_exp

negative_number_literal '0' frac optional_exp int optional_frac optional_exp

int one_nine more_digits

one_nine '1' . '9'

digits digit more_digits

more_digits "" '_' digits digits

optional_frac "" frac

frac '.' digits

optional_exp "" 'e'optional_minus digits

optional_minus "" '-'

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.

-4
0
0.75
12
99.44
1_024
1.024e3

Record

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 "" field more_fields indent field more_open_fields outdent

field text_literal field_value name optional_field_value

field_value ':' space expression input_list space body

optional_field_value "" field_value

more_fields "" ',' space field more_fields

more_open_fields "" linebreak field more_open_fields

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"
}

and

def stooge: {}
assign stooge.first: "Curly"
assign 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: {
    aliceblue
    antiquewhite
    aqua
}

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

There is also a form for creating function fields (aka records).

def object: {
    double: function double(x) (x + x)
}

def object: {
    double(x) (x + x)
}

Keys

Keys can be

An invalid key type yields null on reading, and a disrupt 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.

Fields with stone record keys can only be inserted with an assign statement. Record literals do not permit stone record keys. Stone record keys make it possible to put secret fields in records. Those fields can only be inserted and retrieved with the use of a specific stone record. If you do not have the secret key, the record appears to be an ordinary record. Stone record key fields are not copied by the intrinsic record function. Stone record keys are also omitted by the intrinsic array function.

Fields

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).

Example:

var stooge: {first: "Curly", last: "Howard"}
var first_name: stooge.first       # first_name is "Curly"
assign first_name: null.first         # first_name is null
assign new_stooge: record(stooge)
assign new_stooge.first: "Shemp"      # new_stooge is {first: "Shemp"}
assign 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.

Example:

def stooge: {first: "Curly", last: "Howard"}
assign first_name: stooge["first"]           # first_name is "Curly"
assign stooge.first: "Jerome"                # {first: "Curly", last: "Howard"}
assign stooge.middle: "Lester"               # {first: "Curly", middle: "Lester", last: "Howard"}
assign stooge[null]: "Mogo on the Gogogo"    # disrupt
assign stooge: {}                            # disrupt

Delete

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

assign stooge.first: null

Methods

The method invocation pattern is

record.method_name(input_list)

The record is searched for a field matching the method_name. If the result of that search is not a function, then it disrupts.

Text

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 &ampersand operator or the &&double ampersand operator. The length function is used to determine the number of characters in a text.

Text literals

text_literal quote chevron

quote '"' more_quote_characters '"'

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

more_quote_characters "" quote_character more_quote_characters

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

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

more_hex "" hex more_hex

escape sequence result
\b \backslash
\d »droite
\g «gauche
\n  linefeed
\q "double quote
\r  carriage return
\t  tab
\u{unicode codepoint in hex}  unicode

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.

Examples:

"This is a text."

"So is this."

""    # an empty text

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

"This text contains \qquotes\q."

A text must begin and end on the same line. A text may not contain a line break.

"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 '«' more_chevron_characters '»'

chevron_character '0009'tab '000A'linefeed '000D'carriage return '0020' . '10FFFF' - '«' - '»'

more_chevron_characters "" chevron more_chevron_characters chevron_character more_chevron_characters

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 a single character, not <<. ) These chevron 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. Comments may not be placed inside of chevron text literals.

«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

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]               # null
assign my_text[0]: "r"   # disrupt

Immutability

An immutable object can not be changed or mutated. An attempt to modify a mutable object will disrupt the program.

These values are always immutable: true false null.

Values of these types are always immutable: number text function pattern.

Values of these types are initially mutable, but can be transformed into immutable values: array record blob.

Objects can be made immutable by the stone intrinsic function that turns them to stone.

The state of mutability of a value can be sensed with the stone? intrinsic function.

Immutable objects are generally safer to pass to functions in modules that are not fully trusted.