The Misty Language provides several object types.
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.
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_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
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"
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.
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_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
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.
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 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.
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
A field can be deleted by replacing its value with null
.
assign stooge.first: null
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.
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_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
'«'
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 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
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.