MOO Programming Language Syntax Description
What follows is a more terse summary of the MOO programming language syntax as implemented in mooR. This is meant as a reference for those familiar with the language, rather than a tutorial.
Introduction
MOO is an object-oriented programming language designed for use in MOO environments. It is a dynamic, interpreted language that allows for rapid development and prototyping.
Its syntax has some similarities in style to Wirth-style languages (like Pascal) because it has a keyword-based block syntax and 1-based indexing, but it also has a more C-like syntax for expressions and operators, and some functional programming inspirations (immutable collections, list comprehensions, etc.) though it does not (yet) have first-class functions or lambdas.
Objects in MOO differ from objects in most other object-oriented programming languages you are likely familiar with.
In MOO, objects are persistent database entities. They are not garbage collected, and are referred to using literals
like #123
or $room
. Changes made to objects are permanent and can be accessed by other users or processes.
MOO also has a different inheritance model than most object-oriented languages. Objects can inherit properties and verbs from other objects, but there are no "classes." This model of inheritance is called "prototype inheritance" and is similar to the model in the Self language. Each object has at most one parent, and properties and verbs are looked up in the parent if they are not found in the object itself. New objects can be created with any other existing object as a parent, providing the user has the necessary permissions.
Basic Structure
A MOO program is called a "verb" and consists of a series of statements that are executed in order. There are no subroutines or functions in the traditional sense, but verbs can call other verbs on objects.
The following is a rather terse summary of the MOO syntax. For a more user-friendly overview, please see the LambdaMOO Programmers Manual or various tutorials.
Statements
MOO supports several types of statements:
-
Control Flow Statements:
if
/elseif
/else
/endif
- Conditional executionwhile
/endwhile
- Loop as long as condition is truefor
/endfor
- Iteration over ranges or collectionsfork
/endfork
- Parallel execution threadstry
/except
/finally
/endtry
- Exception handlingbreak
andcontinue
- Loop controlreturn
- Return from the current verb
-
Variable Declaration and Assignment:
let
- Declares local variablesconst
- Declares constantsglobal
- Declares global variables
-
Block Structure:
begin
/end
- Groups statements into a block
-
Expression Statements:
- Any expression followed by a semicolon
Variables and Types
MOO supports several basic data types:
-
Primitive Types:
- Integer (
INT
) - Whole numbers - Float (
FLOAT
) - Decimal numbers - String (
STR
) - Text in double quotes - Binary (
BINARY
) - Binary data in base64 format withb"
prefix, e.g.b"SGVsbG8gV29ybGQ="
- Boolean (
BOOL
) -true
orfalse
- Object (
OBJ
) - References to objects in the DB, written as#123
or$room
. Note that$
is a special prefix for "system" objects, which are objects referenced off the system object#0
.$room
is short-hand for#0.room
. - Error (
ERR
) - Error values, literal values starting withE_
, optionally followed (in parentheses) by a string describing the error. For example,E_PERM("Permission denied")
orE_PERM
. - Symbol (
SYM
) - Symbolic identifiers prefixed with a single quote, as in Scheme or Lisp, e.g.'symbol
- Integer (
-
Complex Types:
-
List (
LIST
) - Ordered collections in curly braces{1, 2, 3}
. Lists can contain any type of value, including other lists. Note that unlike most programming languages (and like Pascal, Lua, Julia, etc.) lists are 1-indexed, not zero-indexed. -
Map (
MAP
) - Key-value collections in square brackets[key -> value]
-
Flyweight (
FLYWEIGHT
) - Lightweight objects with structure<parent, [slots], {contents}>
-
Note that MOO's lists and maps have "opposite" syntax to most programming languages. Lists are
{1, 2, 3}
and maps are [key -> value]
. This is a product of the age of the language, which predates the
introduction of Python and other similar languages that used square brackets for lists and curly braces for maps.
- Type Constants:
INT
,NUM
,FLOAT
,STR
,ERR
,OBJ
,LIST
,MAP
,BOOL
,FLYWEIGHT
,SYM
Expressions
Expressions can include:
-
Arithmetic Operations:
- Addition (
+
), Subtraction (-
), Multiplication (*
), Division (/
), Modulus (%
), Power (^
)
- Addition (
-
Comparison Operations:
- Equal (
==
), Not Equal (!=
), Less Than (<
), Greater Than (>
), Less Than or Equal (<=
), Greater Than or Equal (>=
)
- Equal (
-
Logical Operations:
- Logical AND (
&&
), Logical OR (||
), Logical NOT (!
)
- Logical AND (
-
Special Operations:
- Range (
..
) - Used in range selection and range iteration - In-range (
in
) - Tests if a value is in a sequence (list or map)
- Range (
-
Conditional Expression:
expr ? true_expr | false_expr
- Ternary conditional expression the same as C's?:
operator.
-
Variable Assignment:
var = expr
- Assigns value to variable
-
Object Member Access:
- Property access:
obj.property
orobj.(expr)
- Verb call:
obj:verb(args)
orobj:(expr)(args)
- System property or verb:
$property
(looks on#0
for the property)
- Property access:
-
Collection Operations:
- Indexing:
collection[index]
- Range indexing:
collection[start..end]
- List or map assignment:
list[index] = value
- Assigns value to a specific index or key in a list or map - Scatter assignment:
{var1, var2} = list
- Unpacks a list into variables. Has support for optional and rest variables:{var1, ?optional = default, @rest} = list
- Indexing:
-
Special Forms:
- Try expression:
`expr!codes => handler`
- Evaluatesexpr
and handles errors - Range comprehension:
{expr for var in range}
- Creates a list from a generator expression - Range end marker:
$
- Represents the end of a list in range operations
- Try expression:
Control Structures
Conditional Execution
if (condition)
statements
elseif (another_condition)
statements
else
statements
endif
Loops
while (condition)
statements
endwhile
Labeled loops (can be targeted by break
and continue
):
while label (condition)
statements
endwhile
For Loops
The for
loop has several syntaxes depending on the type of iteration, and will work over both lists and maps.
Iteration over a collection:
for item in (collection)
statements
endfor
Iteration with index/key:
For lists:
for value, index in (collection)
statements
endfor
For maps:
for value, key in (collection)
statements
endfor
(Note the "backwards" order of the arguments, which is done to preserve backwards compatibility with the original iteration syntax.)
Iteration over a range:
for i in [start..end]
statements
endfor
Parallel Execution
fork (seconds)
statements
endfork
Labeled forks:
fork label (seconds)
statements
endfork
Exception Handling
try
statements
except (error_codes)
statements
endtry
With a variable capturing the error:
try
statements
except err_var (error_codes)
statements
endtry
With a finally clause:
try
statements
finally
cleanup_statements
endtry
Function Calls
- Built-in Functions:
function_name(arg1, arg2)
- Verb Calls:
object:verb(arg1, arg2)
- System verb Calls:
$system_verb(arg1, arg2)
Performs an attempted dispatch to #0:system_verb(arg1, arg2)
.
- Pass Expression (delegates to a parent object's implementation):
pass(arg1, arg2)
Variable Declaration and Assignment
- Local Variables:
Variables can be declared either implicitly or explicitly.
Implicit variables are declared without a let
keyword, and become present in the scope at their first use:
myvar = 5;
myvar = 10; // Reassigns the variable
Explicit variables are declared with the let
keyword, and become present in the scope at the point of declaration:
let var = expr;
let var; // Default initialized
- Constants:
Constants are declared with the const
keyword and cannot be reassigned after their initial assignment:
const var = expr;
- Global Variables:
Global variables are declared with the global
keyword and can be accessed from any scope, but should be used
sparingly:
global var = expr;
- Scatter Assignment (unpacking):
let {var1, var2} = list;
let {var1, ?optional = default, @rest} = list;
Advanced Features
- Flyweights - Lightweight objects with parent, properties, and contents:
<parent_obj, [prop1 -> value1, prop2 -> value2], {content1, content2}>
- Maps - Key-value pairs:
[key1 -> value1, key2 -> value2]
- For List/Range Comprehensions
List generation from iteration:
{expr for var in (collection)}
or
{expr for var in [start..end]}
e.g.
{ x * 2 for x in ({1, 2, 3, 4}) }
and
{ x * 2 for x in [1..10] }
Conclusion
This overview captures the syntax of the MOO programming language as defined in the grammar. It's a rich language with features for object-oriented programming, functional programming concepts, error handling, and parallel execution.