Table of Contents

How To Use Functions

Use a function when the same calculation or action is needed more than once.

A function gives that code a name. The script can then call the function whenever it needs that work done.

Functions are useful for:


Define And Call A Function

Define a function with `function`, a name, parentheses, and a block.

function ToolRadius(diameter)
{
    return diameter / 2;
}
 
radius = ToolRadius(6);
radius;

The final result is `3`.

The function definition creates the function. The line `ToolRadius(6)` calls it.


Define Functions At Top Level

User functions are normally defined at top level in a script or include file.

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

Do not define user functions inside `if`, `loop`, `while`, `for`, or another function.

A `function` inside a class body defines a method for that class, not a normal top-level function.


Pass Values Into A Function

Values passed to a function are called arguments. Names inside the function parentheses are parameters.

function Area(width, height)
{
    return width * height;
}
 
result = Area(40, 25);
result;

The final result is `1000`.

Here, `40` is passed into `width`, and `25` is passed into `height`.

Arguments can be variables or calculations.

w = 40;
h = 25;
 
Area(w, h);
Area(20 + 20, 5 * 5);

Return A Value

Use `return` when the function should produce a result.

function ClearanceZ(surface_z, clearance)
{
    return surface_z + clearance;
}
 
safe_z = ClearanceZ(12, 5);
safe_z;

The final result is `17`.

A returned value can be stored in a variable, printed, or used inside another calculation.

print('safe z ', ClearanceZ(12, 5));
travel = ClearanceZ(12, 5) + 10;

Use return To Stop Early

`return` also stops the function immediately.

function DivideOrNone(a, b)
{
    if(b == 0)
    {
        return none();
    };
 
    return a / b;
}
 
DivideOrNone(10, 2);    // 5
DivideOrNone(10, 0);    // none()

This is useful for special cases and safety checks.


Use Functions For Checks

A function can make repeated checks easier to read.

function IsProbeErrorOk(error)
{
    return error <= 0.05;
}
 
probe_error = 0.03;
 
if(IsProbeErrorOk(probe_error))
{
    print('probe result ok');
}
else
{
    print('probe error too large');
};

The `if` statement reads like the intent: check whether the probe error is OK.


Use Local Temporary Values

Inside a function, use `set` for temporary local values.

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

The local variable `radius` exists only during that function call.

Do not use `set` at top level. It is for local variables inside blocks, functions, and methods.


Keep Functions Small

A useful function usually does one clear thing.

Good:

function ToolRadius(diameter)
{
    return diameter / 2;
}
 
function Stepover(diameter, percent)
{
    return ToolRadius(diameter) * percent;
}

Harder to reuse:

function DoEverything()
{
    // calculate tool values
    // read job settings
    // show dialogs
    // run probing
    // print report
}

If a function grows too large, split it into smaller functions with clear names.


Avoid Hidden Changes

A function is easiest to reuse when it returns a value instead of changing many root variables.

Prefer this:

function ProbeStatus(error)
{
    if(error <= 0.01)
    {
        return 'excellent';
    };
 
    if(error <= 0.05)
    {
        return 'acceptable';
    };
 
    return 'failed';
}
 
status = ProbeStatus(0.03);

Avoid this style for reusable code:

function SetProbeStatus(error)
{
    if(error <= 0.05)
    {
        probe_status = 'ok';
    }
    else
    {
        probe_status = 'failed';
    };
}

The second function changes a root variable named `probe_status`. That can be useful in a small script, but it is harder to reuse safely.


Call One Function From Another

Functions can call other functions.

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

This keeps each function simple.


Use Functions From MDI

In MDI, start with `=` to evaluate Expr.

=function Add(a, b)
{
    return a + b;
}
 
Add(2, 3);

This outputs:

5

If the host uses the same session for later MDI input, the function can remain available for the next command. If the host uses a temporary session, the function exists only for that evaluation.


Put Reusable Functions In Include Files

When a function is useful in more than one script, put it in an include file.

// lib/probing/probe_math.expr
function ClearanceZ(surface_z, clearance)
{
    return surface_z + clearance;
}

Then include it from a script:

include './lib/probing/probe_math.expr' as ProbeMath
 
safe_z = ProbeMath::ClearanceZ(12, 5);

Use an alias for reusable include files so function names do not mix with caller names.


Common Mistakes

Defining A Function But Not Calling It

This only defines the function:

function Hello()
{
    print('hello');
}

This calls it:

Hello();

Wrong Number Of Arguments

A function must be called with the number of arguments it expects.

function MoveTo(x, y, z)
{
    print(x, y, z);
}
 
MoveTo(10, 20, 30);   // ok
MoveTo(10, 20);       // error

Forgetting return

A function can return the last value in its body, but using `return` is clearer for most beginner scripts.

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

Using A Function For Data That Belongs Together

If many values and actions belong together, use a class instead of many separate functions.

class ProbeJob()
{
    feed = 100;
 
    function SetFeed(value)
    {
        feed = value;
    }
}

Use functions for reusable actions and calculations. Use classes when you need data and actions kept together.


Try This

In MDI, try:

=function FeedForMaterial(material)
{
    if(material == 'aluminum')
    {
        return 900;
    };
 
    if(material == 'steel')
    {
        return 300;
    };
 
    return 500;
}
 
FeedForMaterial('steel');

The final result is `300`.


See Also


Previous: Repeat code with loops

Next: Use sessions safely

How-To index: How-To Guides