Snip

The VIPS GUI, nip2, has its own scripting language called Snip. Snip is a lazy, higher-order, purely functional, object oriented language. Almost all of nip2’s menus are implemented in it, and nip2 workspaces are Snip programs.

VIPS operations listed in the operation database appear as Snip functions. For example, abs can be used from Snip as:

// absolute value of image b
a = vips_call "abs" [b] [];

However, abs won’t work on anything except the primitive vips image type. It can’t be used on any class, or list or number. Definitions in _stdenv.dev wrap each VIPS operation as a higher level Snip operation. For example:

abs x
    = oo_unary_function abs_op x, is_class x
    = vips_call "abs" [x] [], is_image x
    = abs_cmplx x, is_complex x
    = abs_num x, is_real x
    = abs_list x, is_real_list x
    = abs_list (map abs_list x), is_matrix x
    = error (_ "bad arguments to " ++ "abs")
{
    abs_op = Operator "abs" abs Operator_type.COMPOUND false;

    abs_list l = (sum (map square l)) ** 0.5;

    abs_num n
        = n, n >= 0
        = -n;

    abs_cmplx c = ((re c)**2 + (im c)**2) ** 0.5;
}

This defines the behaviour of abs for the base Snip types (number, list, matrix, image and so on), then classes will use that to define operator behaviour on higher-level objects.

Now you can use:

// absolute value of anything
a = abs b;

and you ought to get sane behaviour for any object, including things like the Matrix class.

You can write Snip classes which present functions to the user as menu items. For example, Math.def has this:

Math_arithmetic_item = class 
    Menupullright "_Arithmetic" "basic arithmetic for objects" {

    Absolute_value_item = class
        Menuaction "A_bsolute Value" "absolute value of x" {
        action x = map_unary abs x;
    }
} 

Now the user can select an object and click Math / Abs to find the absolute value of that object.