Misty Programming Language:Statements

This section describes the statements.

statement assign_statement call_statement def_statement if_statement jump_statement log_statement return_statement send_statement var_statement

statements statement more_statements

more_statements "" linebreak statement more_statements

The assign statement

assign_statement "assign" space name optional_assign_suffix optional_box ':' space expression optional_box

optional_assign_suffix "" assign_suffix

assign_suffix '.' name optional_assign_suffix '[' expression ']' optional_assign_suffix invocation assign_suffix

optional_box "" "[]"

The assign statement is the only instrument of mutation. Mutation is problematic, but sometimes necessary.

The assign statement can replace the value of a variable that was created by the var statement. It can not replace the values of parameters, or names created by def or function.

The assign statement can also act on values that are mutable.

Attempting any of those changes on a stone object halts the actor.

Any other use of assign causes a build error.

Examples:
assign index: index + 1
assign my_little_record.new: value
assign my_little_record.new: value + 1
assign my_little_record.new: null
assign my_little_array[index]: value
assign stack[]: value
assign value: stack[]

The call statement

call_statement "call" space callee

callee name activate

activate selection activate subscript activate invocation activate invocation

The call statement invokes a function and ignores the return value.

The def statement

def_statement "def" space name def_value

def_value ':' space expression parameter_list space body

The def statement defines a read-only variable within the current function. The variable is read-only, but the value it contains may be mutable. Names that are defined with the def statement can not be changed with the assign statement. If the value is mutable, then the value's members or elements may be changed with the assign statement.

If the name is followed by (left paren instead of a :colon, then a function literal having the same name as the function is created and given the value of the function object. These two statements do a similar thing:

def double: function double(number) {
    return number + number
}

def double(number) {
    return number + number
}

Within a function, variables must be declared before they are used, except that inner functions can aways see names made by the function form of the def statement.

Example:
def sqrt_2: 1.4142135623730950

def thing_1(x) {
    if x > 0
        return thing_2(x - 1)	# thing_2 has not been declared yet, but thing_1 can see thing_2
    fi
    return x
}

def thing_2(x) {
    if x > 0
        return thing_1(x / 2)
    fi
    return x
}

The jump statement

jump_statement "jump" space callee

The jump statement is a parameterized jump to a function. It is similar to return except that control ultimately goes to the caller's caller, not the caller. In some languages, this is called tail call optimization. It can significantly reduce the rate at which memory is consumed, making looping by recursion and continuation passing style feasible.

The jump statement is not allowed in functions that make inner functions.

Example:
def factorial(n progress | 1) {
    if n > 1
        jump factorial(n - 1 n * progress)
    else
        return progress
    fi
}

The if statement

if_statement then_clause "fi"

then_clause "if" space expression indent statements outdent else_clause

else_clause "" "else" else_consequence

else_consequence space then_clause indent statements outdent

The if statement creates forks in the control flow of a function. The else if form makes it possible to have alternatives without deep indentation. The if statement can be nested.

Example:
if first_name = "Curly" \/ first_name = "Moe" \/ first_name = "Shemp"
    assign last_name: "Howard"
else if first_name = "Larry"
    assign last_name: "Fine"
else
    assign last_name: "(unknown)"
fi

if fee
    if fie
        assign ok: fee
    fi
else
    assign ok: fie
fi

if character(list[at].op) = "j"
    assign list[at].yz: list[at].yz - 1
else if list[at].op = "opx"
    assign list[at].yz: list[at].yz + 1
fi
assign at: at + 1

An if statement may contain def and var statements only if the name being defined appears in both the then branch and the else branch. The name is visible to the rest of the function.

Example:
if allowed!
    def restricted: true
else
    def restricted: false
fi

The log statement

log_statement "log" channel ':' space expression

channel name

The log statement sends the value of an expression to a channel (or log actor). It is used to capture information about the execution of the program for analysis and administration. Logs can provide insight into the operation of a system.

A channel has a status for each program or module according to policy:

A log channel can have any name. For example:
abort abuse account activity adventure alarm alert alpha analysis anomaly audit authorization beta billing breech budget bug catastrophic cause checklist cloud compliance console contract crash criminal dashboard data dayfile debug delay delta demo development disaster disconnect disruption down emergency epic error event evidence example exception exec exhausted experimental expired failover failure fantasy fatal fault feature finished format fraud frontier gamma government guest hallucination halt heartbeat hello host hygiene idle ignore illegal inconsistent info intervention key kyc legal limit local log loss major main maintenance malfunction measurement memory metric migration minor mishap module money monitor motivation network normal null offline online operations overload page panic partition partner permission policy portal practice privacy probe program progress protocol prototype public quality quantum range recover region regulation reject remote reset risk routine sample scope security serious service simulation situation spam special sponsor start state statistics stop storage store stress summary super support suspend suspicious syntax system telemetry test time tomorrow tool trace training transition trend trial trivial type unknown unneeded up usage vault verbose violation warning web world

Logging does not change the behavior of a program. There will be no response.

If a log channel is allowed, then messages are sent to a log actor that is monitoring that channel. It might tabulate, summarize, record, or pass on the event. Unlike send messages, log messages are sent immediately, not waiting for the successful completion of the turn. However, if log is abused, the actor halts.

Example:
log debug: "index" && index

The return statement

return_statement "return" return_value

return_value "" space expression

The return statement provides for the normal exit of a function and the specification of its return value.

If a return value is not provided, then null is assumed. A function may return null implicitly by falling thru the bottom.

Example:
def double(number) {
    return number * 2
}

def abort() {
    assign defcon: 1
    call launch_all_missiles()
}

The send statement

send_statement "send" space expression ':' space expression callback

callback "" ':' space expression

The send statement sends a message to another actor. The left expression must resolve to an actor address object or a message object that is expecting a reply because it was sent with a callback. The right expression is a record containing the outgoing message. The outgoing message record must not contain functions or patterns or cyclic structures.

If a callback function is included, then the callback function receives the reply, not the receiver function. See callback.

Example:
send server: message: reply_callback

The var statement

var_statement "var" space name ':' space expression

The var statement creates a variable in the current function scope. Note that : expression is not optional. The value of a variable may be replaced by the assign statement. The name is the name of a new variable in this scope. The expression on the right side of the :colon gives the initial value of the variable. The name may not be used in the expression on the right side of the :colon.

Within a function, variables must be declared before they are used.

Examples:
var first_name: ""
var last_name: ""
var node_nr: 0