Next: 6.5 Naming conventions Up: 6. Programming Previous: 6.3 Using an external Contents

# 6.4 Syntax

The most basic sort of definition looks like this:

> | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `// very simple!` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `fred = 12` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

This defines a function called `fred` whose value is the number 12. The `//` marks a comment: everything to the end of the line is skipped. Case is distinguished, so `Fred` and `fred` are two different functions. You can use letters, numbers, underscores and single quotes in function names.

Functions may take parameters:

> | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `/* A function with parameters.` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `*/` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `jim a b = a + b + 12` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

This defines a function called `jim` which takes two parameters and whose value is the sum of the two parameters, plus 12. The `/*` and `*/` enclose a multi-line comment.

Functions may have several right-hand-sides, each right-hand-side qualified by a guard expression. Guards are tested from top to bottom, and the first guard which has the value `true` causes the function to have the value of that right-hand-side. If no guard evaluates to `true`, then the last right-hand-side is used.

> | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `jenny a b` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> |  | `=` |  | `42, a + b >= 100` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> |  | `=` |  | `43, a + b >= 50` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> |  | `=` |  | `44` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

This defines a function called `jenny` which takes two parameters and whose value is 42 if the sum of the parameters is 100 or greater; 43 if the sum is greater than or equal to 50 but less than 100; and 44 if the sum is less than 50.

Any function may be followed by any number of local functions, enclosed in curly braces. So `jenny` could be written as:

> | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `jenny a b` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> |  | `=` |  | `42, sum >= 100` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> |  | `=` |  | `43, sum >= 50` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> |  | `=` |  | `44` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `{` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> |  | `sum = a + b;` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `}` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

Note that you need a semi-colon after each local function. A local function may refer to anything in an enclosing scope, including itself.

You can write `if-then-else` expressions:

> | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `david a = if a < 12 then "my cat"` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> |  |  |  | `else "likes lasagne"` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

This is exactly equivalent to:

> | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `david a` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> |  | `=` |  | `"my cat", a < 12` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> |  | `=` |  | `"likes lasagne"` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

`if-then-else` expressions are sometimes easier to read than guards.

Functions application is with spaces (juxtaposition). For example:

> | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `harry = jim 2 3` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

defines `harry` to have the value 17.

All functions are curried, that is, they can accept their arguments in stages. For example:

> | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` | `` |  | `` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
> | `sandro = jim 1` |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |

defines `sandro`, a function which takes one parameter and will add 13 to it. This trick becomes very useful with list processing, see §6.8.

`nip2` has some built-in functions, see Table 6.1. They mostly take a single argument.

Table 6.1: `nip2` built in functions
Function | Description
`error` [char] | Stop with error message
`print` any | Convert to string
`expand` [char] | Expand environment variables in string
`is_image` any | Test for image
`is_bool` any | Test for boolean
`is_real` any | Test for real
`is_class` any | Test for class
`is_char` any | Test for char
`is_list` any | Test for list
`is_complex` any | Test for complex
`is_instanceof` [char] any | Test for instance of class
`has_member` [char] any | Does class have member
`get_member` [char] class | Extract member from class
`re` image`|`complex`|`class | Extract real part of complex
`im` image`|`complex`|`class | Extract imaginary part of complex
`hd` list | Extract head of list
`tl` list | Extract tail of list
`sin` image`|`number`|`class | Sine
`cos` image`|`number`|`class | Cosine
`tan` image`|`number`|`class | Tangent
`asin` image`|`number`|`class | Arc sine
`acos` image`|`number`|`class | Arc cosine
`atan` image`|`number`|`class | Arc tangent
`log` image`|`number`|`class | Natural log
`log10` image`|`number`|`class | Base 10 log
`exp` image`|`number`|`class | e to the power
`exp10` image`|`number`|`class | 10 to the power
`ceil` image`|`number`|`class | Round up
`floor` image`|`number`|`class | Round down
`vips_image` [char] | load image from file

Next: 6.5 Naming conventions Up: 6. Programming Previous: 6.3 Using an external Contents