Sidebar

Home



Expressions V4


Tutorials

How-To

Reference

  Lexical basics
  Type system
  Variables and assignment
  Operators
  Expression rules
  Control flow
  Functions
  Built-in functions
   None and NaN
   Arithmetic
   Algebra
   Logarithmic and Exponential
   Trigonometric
   Rounding and Centering
   Strings
   Output, Formatting, Clipboard, and Errors
   Dialog Functions
   Platform and Paths
  Methods and properties
  Built-in methods
   Common Value Methods
   Number Methods
   String Basic Methods
   String Slice Methods
   String Parsing Methods
   String Formatting Methods
   String Regex Methods
   String Trim and Case Methods
  Objects
  Built-in objects
   Global objects
    settings
    controller
    session
    python
   Collections
    array
    map
    bytes
   File Format I/O
    image_data
    image_stream
   Utils
    crypto
    timer
   Comm
    serial
   Dialogs
    file_open
    file_save
    msg_ok
    msg_ok_cancel
    msg_yes_no
    msg_password
   GUI objects
    window
    panel
    group
    splitpanel
    label
    textbutton
    drawablebutton
    togglebutton
    togglegroup
    textinput
    textedit
    numinput
    slider
    combobox
    listbox
    progressbar
    led
    separator
    menu
    image
    snake
  Classes and user-defined objects
  Include system
  Error model
  Execution model and sessions
  Host integration
  Limits and performance
  Formal reference
  Glossary

Cookbook

exprv4:reference:variables_and_assignment

Variables and Assignment

Variables store values. Expr variables are created dynamically; there is no separate declaration syntax for normal variables.

speed = 1200;
depth = 2.5;
name = 'Tool 1';

Assignment stores a value and also produces the assigned value.

a = 10;
b = a = 5;

After this script, both `a` and `b` are `5`.


Variable Creation

Plain assignment creates a variable if it does not already exist.

speed = 1200;

Reading an unknown variable returns `none()`.

missingValue;       // none()

This allows scripts to check for missing values explicitly:

if(missingValue.is_none())
{
    print('missing');
};

The `set` keyword creates a local variable in the current scope.

if(true)
{
    set temp = 42;
};

`set` is for local temporary values inside a block, function, or method. Use normal assignment at top level.

speed = 1200;       // top-level variable

`set` is not valid at top level.


Scope Categories

Expr resolves variable names through scopes.

The main categories are:

  • local scope
  • root/session scope
  • object scope

Local Scope

Local variables are created with `set` or by function/method parameters.

function Add(a, b)
{
    set sum = a + b;
    return sum;
}

Here, `a`, `b`, and `sum` are local to the function call.

A local variable exists only inside its current block, function, or method scope.

if(true)
{
    set temp = 5;
};
 
temp;       // none()

Root / Session Scope

Root variables are stored in the active Expr session.

count = 1;
count = count + 1;

Root/session variables can persist across evaluations when the host evaluates scripts in the same named session.

Different sessions are isolated from each other.

If evaluation runs without a persistent session, variables exist only during that evaluation.

Object Scope

Inside class constructors and methods, plain assignment can create or update object fields.

class Counter()
{
    value = 0;
 
    function Inc()
    {
        value = value + 1;
        return value;
    }
}
 
c = Counter();
c.Inc();
c.value;        // 1

Inside object context, assignment is object-first after local variables are considered.


Name Resolution For Assignment

Assignment chooses where to store a value using the current context.

For normal assignment `name = value`:

  1. If a matching local variable exists, it is updated.
  2. Otherwise, inside object context, a matching object field is updated or a new object field is created.
  3. Otherwise, a root/session variable is updated or created.

Example with local shadowing:

a = 5;
 
if(true)
{
    set a = 10;
    a;          // 10
};
 
a;              // 5

The local `a` hides the outer `a` only inside the block.

Example with object fields:

value = 100;
 
class Counter()
{
    value = 0;
 
    function Inc()
    {
        value = value + 1;
    }
}
 
c = Counter();
c.Inc();
 
value;      // 100
c.value;    // 1

The assignment inside `Inc()` updates the object field. It does not update the same-named root variable.


set

`set` creates a local variable in the current scope.

set localName = value;

Use `set` for temporary helper values:

function ToolArea(diameter)
{
    set radius = diameter / 2;
    return pi() * radius ** 2;
}

After a local variable has been created, normal assignment updates it while it is in scope.

a = 1;
 
if(true)
{
    set a = 2;
    a = a + 3;
    a;          // 5
};
 
a;              // 1

`set` always creates a local variable. It does not update an outer variable or object field.

Inside a method, this creates a local variable named `value`:

class Counter()
{
    value = 10;
 
    function Preview()
    {
        set value = this.value + 1;
        return value;
    }
}

The object field remains unchanged.


Assignment Operators

Expr supports these assignment and update forms:

Form Meaning
a = b normal assignment
a += b add and assign
a -= b subtract and assign
a *= b multiply and assign
a /= b divide and assign
a %= b modulo and assign
a **= b power and assign
a &= b bitwise AND and assign
a |= b bitwise OR and assign
a ^= b bitwise XOR and assign
a <<= b shift left and assign
a >>= b shift right and assign
++a pre-increment
a++ post-increment
--a pre-decrement
a-- post-decrement

Logical compound assignment operators are not part of Expr syntax:

a &&= b;     // not supported
a ||= b;     // not supported
a ^^= b;     // not supported

Assignment Associativity

Normal assignment is right-associative.

a = b = 3;

This behaves like:

a = (b = 3);

Both `a` and `b` become `3`.

Compound assignment is also right-associative.

a = 1;
b = 2;
a += b += 3;

This behaves like:

a += (b += 3);

`b` becomes `5`, then `a` becomes `6`.


Compound Assignment

Compound assignment updates a variable using its current value.

a = 10;
a += 5;      // same result as: a = a + 5

Compound assignment returns the assigned value.

a = 1;
b = (a += 4);

After this script, both `a` and `b` are `5`.

Compound assignment reads the target value before evaluating the right side, then stores the computed result.

a = 10;
function ChangeA()
{
    a = 100;
    return 5;
}
 
a += ChangeA();

The compound operation uses the original target value `10` and the right-side result `5`, so `a` becomes `15`.

The operator part keeps the same operand rules as the normal operator:

  • += uses `+` rules.
  • /= uses division rules.
  • &=, |=, ^=, <<=, and >>= require valid numeric operands.
  • invalid operands produce errors.

Example:

a = 10;
a += none();      // error

Increment and Decrement

++ and -- require a modifiable numeric variable.

Prefix form updates first and returns the new value:

a = 1;
b = ++a;

After this script, `a` is `2` and `b` is `2`.

Postfix form returns the old value and then updates:

a = 1;
b = a++;

After this script, `a` is `2` and `b` is `1`.

The same rule applies to decrement:

a = 3;
b = --a;     // a is 2, b is 2
c = a--;     // c is 2, a becomes 1

These forms are invalid because the target is not a modifiable variable:

++1;         // error
(1 + 2)++;   // error

Assignment and none()

Explicitly assigning `none()` clears or unsets a variable.

a = 10;
a = none();
a;              // none()

This applies to local variables too:

{
    set temp = 1;
    temp = none();
    temp;       // none()
}

There is one special rule for normal assignment from block-style keyword expressions.

If the right side is a block-style keyword expression that produces no value, normal assignment skips the update.

a = 10;
a = if(false)
{
    20;
};
 
a;              // 10

The `if` expression produced no value, so `a` was not changed.

Compound assignment does not use this skip behavior.

a = 10;
a += if(false)
{
    20;
};

This fails because compound assignment tries to calculate `10 + none()`.


Protected System Object Names

Some root names are reserved for system-provided objects.

These names cannot be overwritten by assignment:

state = 1;       // error
settings = 1;    // error
gcode = 1;       // error

Use the methods or properties provided by those objects instead of replacing the object itself.


Property Assignment

Reading object properties from outside the object is supported when the object exposes the property:

tool.Number;

Direct property assignment from outside the object is not supported:

tool.Number = 2;     // not supported

Use an object method to change object state:

tool.SetNumber(2);

Inside a class constructor or method, assign the field by name:

class Tool(number)
{
    Number = number;
 
    function SetNumber(number)
    {
        Number = number;
    }
}

Lifetime and Persistence

Local variables live only for their scope.

if(true)
{
    set temp = 5;
};
 
temp;       // none()

Root/session variables persist across evaluations within the same named session.

count = 1;

A later evaluation in the same session can read and update `count`.

Different sessions are isolated. A variable created in one session is not visible in another session.

If the host evaluates Expr without a persistent session name, variables are effectively non-persistent between separate evaluations.

Functions and classes can also persist in named sessions. Their details are covered in later reference chapters.


Practical Rules

Use normal assignment `=` when:

  • creating or updating a root/session variable
  • intentionally updating shared script state
  • creating or updating object fields inside class constructors or methods

Use `set` when:

  • the value is temporary
  • the value should disappear after the current block, function, or method
  • you want to avoid accidentally updating an outer variable or object field

Use compound assignment when the update is simple and obvious:

count += 1;
total += value;

Avoid compound assignment when the right side has important side effects or may produce `none()`.

Previous: Type system

Next: Operators

exprv4/reference/variables_and_assignment.txt · Last modified: by 127.0.0.1

Page Tools