exprv4:tutorials:none_nan_and_errors



none(), nan(), and Errors

Expr has two special values that are important in real scripts:

  • `none()` means no value.
  • `nan()` means not a valid number.

They are different and should be handled differently.

You will see `none()` when a value is missing. You will see `nan()` when a numeric result is invalid or unknown.


none() Means No Value

`none()` represents a missing value.

a = none();
a.is_none();

The final value is `true`.

Reading an unknown variable also returns `none()`.

missingValue;

The final value is `none()`.

This is useful because a script can detect missing values instead of always failing immediately.


none() Is False In Conditions

`none()` behaves as false in conditions.

if(none())
{
    'runs';
}
else
{
    'does not run';
};

The final value is `'does not run'`.

You can test for `none()` explicitly:

value = none();
 
if(value.is_none())
{
    'missing';
}
else
{
    'available';
};

The final value is `'missing'`.


none() Is Not Zero

`none()` is not the same as `0`.

none() == 0;     // false
none() == none();

The second expression is true.

Do not use `none()` in numeric calculations.

5 + none();      // error

If a numeric value may be missing, check it before using it.

value = none();
 
if(value.is_none())
{
    result = 0;
}
else
{
    result = value + 5;
};

if Without else Can Produce none()

An `if` without an `else` produces `none()` when its condition is false.

value = if(false)
{
    10;
};
 
value.is_none();

The final value is `true`.

This can be useful, but it can also cause errors if you use the result as a number.

result = 5 + if(false)
{
    10;
};

This fails because the `if` produces `none()`.

Use an `else` branch when a value is required.

result = 5 + if(false)
{
    10;
}
else
{
    0;
};

The final value of `result` is `5`.


Assignment and none()

Assigning `none()` explicitly clears or unsets the variable.

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

The final value is `none()`.

There is one special assignment behavior with block-style control expressions.

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

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

The final value is still `10`.

This protects existing values when an optional block produces no result.

Compound assignment does not use this skip behavior.

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

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


nan() Means Not a Valid Number

`nan()` is a numeric value that means “not a valid number”.

value = nan();
value.is_nan();

The final value is `true`.

NaN can appear when a numeric operation or parsing step cannot produce a valid normal number.

value = nan() + 1;
value.is_nan();

The final value is `true`.

NaN often propagates through numeric calculations.


nan() Is False In Conditions

`nan()` behaves as false in conditions.

if(nan())
{
    'runs';
}
else
{
    'does not run';
};

The final value is `'does not run'`.

Use `.is_nan()` when you specifically need to detect NaN.

value = nan();
 
if(value.is_nan())
{
    'invalid number';
}
else
{
    'valid number';
};

Checking For Valid Numbers

Use `.is_num_notnan()` when a value must be a valid finite number.

speed = 1200;
 
if(speed.is_num_notnan() && speed >= 0)
{
    'valid speed';
}
else
{
    'invalid speed';
};

This is useful before calculations that must not receive missing or invalid numeric values.

function SafeDivide(a, b)
{
    if(!a.is_num_notnan() || !b.is_num_notnan())
    {
        return none();
    };
 
    if(b == 0)
    {
        return none();
    };
 
    return a / b;
}
 
SafeDivide(10, 2);

The final value is `5`.


Common Runtime Errors

Some errors happen while a script is running.

Common runtime errors include:

  • Using `none()` in arithmetic.
  • Calling a function or method with the wrong number of arguments.
  • Calling an unknown function or method.
  • Dividing by zero.
  • Using an invalid shift count.
  • Passing the wrong type to an operator or method.
  • Creating a loop that reaches the safety limit.

Examples:

5 + none();      // invalid operand
10 / 0;          // division by zero
1 << 64;         // invalid shift count
unknownFunc();   // undefined function

Parse Errors

Parse errors happen before the script runs. They are syntax errors.

Common parse errors include:

  • Missing semicolon.
  • Missing closing `)` or `}`.
  • Missing `:` in a conditional operator.
  • `break` or `continue` outside a loop.

Example:

a = 10
b = 20;

The first line is missing a semicolon.


User Errors

Use `error(…)` when your script should stop with a clear message.

speed = -1;
 
if(!speed.is_num_notnan() || speed < 0)
{
    error('Invalid speed value');
};

This is useful in probing, ATC, dialogs, and machine workflow scripts where continuing with bad input would be unsafe or confusing.

Use specific error messages. They make debugging much easier.


Defensive Checks

Check assumptions before important operations.

function RequirePositiveNumber(value, name)
{
    if(!value.is_num_notnan())
    {
        error(name + ' must be a valid number');
    };
 
    if(value <= 0)
    {
        error(name + ' must be positive');
    };
 
    return value;
}
 
depth = RequirePositiveNumber(2.5, 'Depth');

Use this style for values that affect machine movement, probing decisions, tool changes, output control, or generated G-code.


Choosing Between none(), nan(), and error()

Use `none()` when:

  • A value is optional.
  • A result is missing but the script can continue.
  • A function wants to say “no result”.

Use `nan()` when:

  • A value is numeric but invalid or unknown.
  • You want invalid numeric state to propagate through calculations.

Use `error(…)` when:

  • The script should stop.
  • Continuing would be unsafe.
  • The user should see a clear message.

Common Mistakes

Treating none() Like Zero

Use an explicit fallback.

value = none();
 
if(value.is_none())
{
    value = 0;
};

Checking Only is_num()

`is_num()` can include NaN. If you need a usable number, use `is_num_notnan()`.

value = nan();
value.is_num();          // true
value.is_num_notnan();   // false

Forgetting else When a Value Is Required

If an `if` expression must produce a number, include an `else` branch.


Try This

Read this script and predict the final value:

function ProbeStatus(errorValue)
{
    if(errorValue.is_none())
    {
        return 'missing';
    };
 
    if(!errorValue.is_num_notnan())
    {
        return 'invalid';
    };
 
    if(errorValue <= 0.05)
    {
        return 'ok';
    };
 
    return 'too large';
}
 
ProbeStatus(nan());

The final value is `'invalid'`.

Next: Complete examples

exprv4/tutorials/none_nan_and_errors.txt · Last modified: by 127.0.0.1

Page Tools