# Functions

[This is preliminary documentation and subject to change.]

NAnt provides a rich set of bulitin functions, that allow you to:

- manipulate strings
- manipulate date/time values
- manipulate path names
- read the properties of files/directories
- access current build information and more
- and more

For a full list of supported functions, click here.

### Function Call Syntax

To call functions, use `prefix::function-name(argument1, ..., argumentN)` syntax within expressions. NAnt will (implicitly) try to convert the arguments you pass to functions to correct types and will report an error in case of failure.

For example, assuming you would like to call `string::contains('0123456789',1)` which expects two `string` parameters, but you want to pass the second parameter which is an integer. NAnt would attempt to convert the second parameter from `int` to `string`, which succeeds and function is called as if it was written as `string::contains('0123456789','1')`.

The following table shows the possible type conversions:

From Type | To Type | Allowed | Remarks
--- | --- | --- | ---
`int` | `string` | Yes | The conversion is always possible.
`int` | `double` | Yes | The conversion is always possible.
`int` | `boolean` | No | Can be done with the `if()` conditional operator or simply as `(value <> 0)`
`int` | `datetime` | No | You cannot convert from `int` to `datetime`.
`int` | `timespan` | No | You can use the `timespan::from-xxx` functions to construct a `timespan` from a given number of days, months, ....
`string` | `int` | Yes | If the string doesn't represent an integer value, an error is reported.
`string` | `double` | Yes | If the string doesn't represent a floating point value, an error is reported.
`string` | `boolean` | Yes | If the string isn't either `true` or `false` (case insensitive), an error is reported.
`string` | `datetime` | Yes | If the string doesn't represent a valid date/time, an error is reported. Date/time string format is `MM/DD/YYYY HH:MI:SS`
`string` | `timespan` | No | You can use `timespan::parse` to construct a `timespan` from a time indicated by a given string. If the string doesn't represent a valid timespan, an error is reported.
`double` | `int` | Yes | If the string doesn't represent an integer value, an error is reported.
`double` | `string` | Yes | The converted string uses dot as a fractional part separator so the result looks like `0.1234567`
`double` | `boolean` | No | You cannot convert from `double` to `boolean`.
`double` | `datetime` | No | You cannot convert from `double` to `datetime`.
`double` | `timespan` | No | You can use the `timespan::from-xxx` functions to construct a `timespan` from a given number of days, months, ....
`boolean` | `int` | No | You cannot convert from `boolean` to `int`. You may want to use `if(boolvalue,1,0)` instead.
`boolean` | `string` | Yes | The result is `'True'` or `'False'` string.
`boolean` | `double` | No | You cannot convert from `boolean` to `double`.
`boolean` | `datetime` | No | You cannot convert from `boolean` to `datetime`.
`boolean` | `timespan` | No | You cannot convert from `boolean` to `timespan`.
`datetime` | `int` | No | You cannot convert from `datetime` to `int`.
`datetime` | `string` | Yes | The result is a datetime string with the following format: `MM/DD/YYYY HH:MI:SS`
`datetime` | `double` | No | You cannot convert from `datetime` to `double`.
`datetime` | `boolean` | No | You cannot convert from `datetime` to `boolean`.
`datetime` | `timespan` | No | You can use the value of `datetime::get-ticks` to construct a `timespan` using `timespan::from-ticks`.
`timespan` | `int` | No | You cannot convert from `timespan` to `int`.
`timespan` | `double` | No | You can use `timespan::get-ticks` to convert from `timespan` to `double`.
`timespan` | `boolean` | No | You cannot convert from `timespan` to `boolean`.
`timespan` | `string` | No | You can use `timespan::to-string` to obtain the string representation of a `timespan`.
`timespan` | `datetime` | No | You cannot convert from `timespan` to `datetime`.

### Custom Functions

Just as you can extend NAnt with your own tasks it is also possible to implement your own functions for use in build files.

Functions can be implemented in any .NET language and are loaded in the same manner as tasks. ie either by locating your custom function assembly in the NAnt bin directory or using the `<loadtasks>` task. Example C# code for a Hello World function :

Define a custom function using C#.

    [FunctionSet("hello", "Hello")]
    public class HelloFunctions : FunctionSetBase {
        public HelloFunctions(Project project, PropertyDictionary properties) : base(project, properties) {
        }
        [Function("hello-world")]
        public static string HelloWorldfunc() {
            return "Hello World!!";
        }
    }

and call that function from a build file.

    <echo message="${hello::hello-world()}" />

A quick and easy way to develop new functions is to use the `<script>` task. This allows you to create and test new functions without the overhead of building an external assembly. The `<script>` task documentation contains examples of custom function definitions.