Expressions

Allocations

new and scope keywords are used for allocation (see Memory Management)

append

The append expression allocates memory immediately after an object’s allocated memory, and can only be used in a constructor. (See Memory Management)

An append allocation can be used in any way a new allocation can be used. (See new)

Assignment operations

See Assignment operators

Binary operations

See Binary operators

Bind expression =>

The => expression is used for method binding (see Method References)

box

The box expression allocates an object which wraps a value type. (See Memory Management (boxing))

case

case expressions can be used for pattern matching outside switches. (See [Pattern Matching]http://beef-lang.org/docs/language-guide/pattern/))

Cast expression

Conditional operator

Conditional variable declarations

Variable declarations can be use as boolean expressions in ‘if’ statements for nullable types. These can be used with certain types of binary operations in the cases where a ‘true’ overall ‘if’ result ensures that the conditional variable declaration was also evaluated and resulted in ‘true’.

/* Simple conditional variable declaration */
if (let name = GetName())
{

}

/* 'Complex' conditional variable declaration */
if ((let name = GetName()) && (isEnabled))
{

}

/* This is ILLEGAN since "force" can cause the block to be entered even if the conditional variable declaration fails */
if ((let name == GetName() || (force))
{

}

default

Every type has a “default” value, which is always zero-initialization.

// Default can specify a type and results in a default-initialized value
var str = default(String);
// Default will use the "expected" type if there is no explicit default type specified
String str2 = default;

Expression blocks

Expression blocks end with an expression that is not terminated by a semicolon.

Console.WriteLine("Result={}", 
    { 
        GetByRef(let val);
        val 
    });

Index expressions

Literals

new

The new expression allocates memory in the global allocator or in a custom allocator. (See Memory Management)

All new operations can also accept a custom allocator argument.

Null-conditional operators

Null-conditional operators val?.field and val?[index] will result in null if val is null. The null-conditional operators can be applied in a chain, which will short-circuit to null at the first instance of a null.

int? a = val?.intField;
int? nameLength = val?.name?.Length;

Parentheses expression

Adding parentheses around expressions can be used for changing order of operations for complex expressions.

int a = 1 + 2 * 3; // The multiply happens before the add here, resulting in 7
int b = (1 + 2) * 3; // The add happens before the multiply here, resulting in 9

scope

The scope expression allocates memory on the stack, in a scope contained in an executing method. (See Memory Management)

A scope allocation can be used in any way a new allocation can be used. (See new)

this

this is a special variable name, which represents the current instance in instance methods. If the defining type is a struct then this is a value type (not a pointer), which is mutable for “mut” methods and immutable otherwise.

Tuple expression

The tuple expression is a paranthesized expression containing multiple comma-seperated values, and optionally field names. (See Data Types (Tuples)))

Unary operations

See unary operators

Uninitialized ‘?’

When assigned to a variable or field, ? will cause the value to be treated as if it had an assignment but without (necessarily) any actual operation. This can be useful in cases such as with “buffer” type arrays that don’t need to be zero-initialized before use.