Function overloading allows different function implementations to use the same function name; which function is selected in a given location of your program is determined by the type of the arguments. Using function overloading can make your programs more succinct.

For this example we will write a function that implements a `guzinta` operation. A `guzinta` ("goes into") is a division standing on its head, so that if `6 / 2 = 3`, ```2 guzinta 6 = 3```.

Here is a simple `guzinta` function for `integer`s. Because we want the function name, `guzinta`, to go between its two arguments, rather than before them, we define it as an infix-function.

```  define integer infix-function
value integer a
guzinta
value integer b
as
return b / a

process
local integer i

set i to 3 guzinta 12
output "d" % i
```

This implements the `guzinta` operator for `integer`s. But we may also want to perform a `guzinta` calculation for floating point numbers. Here is the `guzinta` function for `float`s:

```  import "omfloat.xmd" unprefixed

define float infix-function
value float a
guzinta
value float b
as
return b / a

process
local float x

set x to 3.5 guzinta 15.75
output "d" % x
```

This works fine. But what if you want to perform `guzinta` calculations on `integer`s and `float`s in the same program, just as you can perform multiplication, division, addition and subtraction on both types using the same operators? To do this you need two different `guzinta` functions in the same program. To make this possible, there must be a way for OmniMark to tell which function is being called in each case. This is accomplished by defining a pair of `overloaded` functions:

```  import "omfloat.xmd" unprefixed

define overloaded integer infix-function
value integer a
guzinta
value integer b
as
return b / a

define overloaded float infix-function
value float a
guzinta
value float b
as
return b / a

process
local integer i
local integer left  initial { 3 }
local integer right initial { 15 }

set i to left guzinta right
output "d" % i

output "%n"

process
local float x
local float left  initial { 3.5 }
local float right initial { 15.75 }

set x to left guzinta right
output "d" % x

output "%n"
```

This program works for both `integer` and `float` arguments. OmniMark knows which function to call by inspecting the types of the arguments passed to the function. If the arguments are both of type `float`, then the `float` version is called. If the arguments are both of type `integer`, then the `integer` version is called.

What happens if the arguments are of differnet types? What if we add the following lines to our program?

```  process
local float   x
local float   left  initial { 3.5 }
local integer right initial { 15 }

set x to left guzinta right
output "d" % x

output "%n"
```

This code will produce a compile-time error with the message:

```  Operator type mismatch
An argument for operator 'GUZINTA' is of the wrong type. The type
signature encountered is 'FLOAT GUZINTA INTEGER'.
```

This is different from the behavior we would have seen from the original un-overloaded `float` version of the `gunzinta` function. With that version, passing an `integer` value as one of the arguments would have triggered an automatic conversion of the `integer` value to a `float` value, and the function would have executed normally and returned a `float` value.

However, if OmniMark is to use the type of the arguments of an overloaded function to decide which version of the function to call, then it cannot apply an automatic conversion of one type to another. Therefore, when you define overloaded functions, you have to take care of every possible combination of types that could be passed to the functions.

If we want to be able to perform `guzinta` operations on a mix of `float` and `integer` values, therefore, we need to provide overloaded functions for `float guzinta integer` and ```integer guzinta float```. Before we do this, however, we need to decide which type the result the `guzinta` operator should produce for each of these cases. When you perform an operation on data of two different types you risk losing information if you create a result of the wrong type. You therefore need to establish a hierarchy of types. In this case the choice is simple. A `float` contains fractional information while an `integer` does not, so in the case of an operation on `integer`s and `float`s, we want the answer to be expressed as a `float`.

We can define two more functions to cover the `float guzinta integer` and `integer guzinta float` cases:

```  define overloaded float infix-function
value integer a
guzinta
value float b
as
return b / a

define overloaded float infix-function
value float a
guzinta
value integer b
as
return b / a
```

However, if you have more than two data types you need to handle, it will get cumbersome to provide all the possible combinations of types. To avoid this problem we can consolidate some of the variants. The following sample consolidates `float guzinta float` and `float guzinta integer`:

```  define overloaded float infix-function
value (float | integer into float) a
guzinta
value float b
as
return b / a
```

Here we join the different types with the `|` symbol and specify the type into which the arguments must be converted using the `into` keyword. The parentheses are essential, and the `into` part must be specified when using this form.

This leaves us with three overloaded `guzinta` functions:

```  define overloaded integer infix-function
value integer a
guzinta
value integer b
as
return b / a

define overloaded float infix-function
value (float | integer into float) a
guzinta
value float b
as
return b / a

define overloaded float infix-function
value float a
guzinta
value integer b
as
return b / a
```

It is tempting to try and consolidate further by writing a function that looks like this:

```  define overloaded float infix-function
value (float | integer into float) a
guzinta
value (float | integer into float) b
as
return b / a
```

However, this will not work because this definition includes the combination `integer guzinta integer`, which has already been defined. You must make sure that each possible combination of types is defined only once.

There are a couple of types that we still have to include in our function definitions, however. Consider what happens if we try the following calculation with our current set of `guzinta` functions:

```  process
local float x

set x to 3.5 guzinta "15.75"
output "d" % x
```

This program will produce the error:

```  Operator type mismatch
An argument for operator 'GUZINTA' is of the wrong type. The type
signature encountered is 'NUMERIC-LITERAL GUZINTA STRING'.
```

We are used to `string` values and numeric literals (numbers expressed directly in program code) being accepted by OmniMark's mathematical operators. However, these values are both in the form of `string`s, and in an overloaded function, automatic conversion of these `string`s to `integer`s or `float`s is not possible. We have to make the type selection and the conversion explicit by adding overloaded functions to handle them. In doing so, we have to decide what type we will return when a calculation includes an numeric literal or a `string` value. Since we cannot tell in advance whether a `string` or numeric literal contains an `integer` or `float` value, we will make all `guzinta` calculation involving `string`s or numeric literals return `float`s.

Here are the functions to add to our set of `guzinta` functions to support `string` and numeric literal types:

```  ; NUMERIC LITERAL
;
define overloaded float infix-function
value (numeric-literal into float) a
guzinta
value (integer | float | string | numeric-literal into float) b
as
return b / a

define overloaded float infix-function
value (integer | float into float) a
guzinta
value (numeric-literal into float) b
as
return b/a

; STRING
;
define overloaded float infix-function
value string a
guzinta
value (integer | float | string | numeric-literal into float) b
as
return b / a

define overloaded float infix-function
value (integer | float into float) a
guzinta
value string b
as
return b / a
```

The example above uses overloaded functions to introduce a new operator. A more likely use of overloading is to allow you to apply exising operators to new data types. You can create new data types by defining a `record` type. In the example that follows, we will define a type `point` to represent a location in a two dimensional space. We will then implement addition and subtraction operations for the `point` type by overloading the built-in `+` and `-` operators:

```  declare record point
field integer x
field integer y

define overloaded point infix-function
value point a
+
value point b
as
local point c

set c:x to a:x + b:x
set c:y to a:y + b:y

return c

define overloaded point infix-function
value point a
-
value point b
as
local point c

set c:x to a:x - b:x
set c:y to a:y - b:y

return c

process
local point foo
local point bar
local point baz

set foo:x to 7
set foo:y to 9

set bar:x to 2
set bar:y to 3

set baz to foo + bar

output "baz:x = " || "d" % baz:x
|| "%n"
|| "baz:y = " || "d" % baz:y
```

### Overloaded functions and extended types

The example above deals with basic `record` types. You may also want to create overloaded functions to deal with different members of a set of extended record types. An important feature of extended `record` types is that if a `record` is an extension of another `record` type it can be used as an item of that `record` type. For example, a `record` type `point`:

```  declare record point
field integer x
field integer y
```
can be extended to create a `record` type `pixel` by adding a `color` field:
```  declare record pixel extends point
field string color
```

Now suppose that we want to create a display function for all things pointy (that is, all types that are extensions of `point`). We cannot simply create a pair of overloaded `display` functions:

```  define overloaded string function
display (value point p)
as
return "d" % p:x || ", " || "d" % p:y

define string function
display (value pixel p)
as
return "d" % p:x || ", " || "d" % p:y || ": " || p:color
```

This will cause OmniMark to complain that a `display` function has already been defined for type `pixel` because a `pixel` can be used as a `point` and there is already a `display` function for a `point`. The OmniMark compiler therefore cannot tell which function should be called when the function name is invoked with an argument of type `pixel`.

To avoid this problem you need a dynamically overloaded function, that is, one in which the particular function to execute is chosen while the program is running based on the particular type of the argument that is passed to it.

To do this, you write a `dynamic` function for the base type:

```  define dynamic string function
display (value point p)
as
return "d" % p:x || ", " || "d" % p:y
```

This function is the starting point for selecting a function to invoke for any argument type that is an extension of `point`. It is the `dynamic` function for `point` and its extensions. The specific functions for the individual extensions of `point` are not themselves `dynamic` functions, but `overriding` functions. That is, the `dynamic` function for `point` will be selected for arguments of type `point` and all extensions of type `point` unless there is an `overriding` function defined for the specific type of the argument. Here is an overriding function for type `pixel`.

```  define overriding string function
display (value pixel p)
as
return "d" % p:x || ", " || "d" % p:y || ": " || p:color
```

Here is how these dynamic functions might get called. Notice that the decision about which function to call must be made at run time since the same function call in the repeat loop has a different argument type each time:

```  process
local point p variable
local point a
local pixel b

set a:x to 5
set a:y to 89

set b:x to 76
set b:y to 231
set b:color to "cyan"

set new p to a
set new p to b

repeat over p as p
output display (p)
again
```

It is very possible that you will want to define `display` functions for many different `record` types. You can do this by defining functions that are both statically and dynamically overloaded. Here is a dynamic display function definition for the root type publication and one of its extensions, novel:

```  define dynamic string function
display (value publication p)
as
return p:name || "%n"

define overriding string function
display (value novel n)
as
return n:name || " a " || n:genre || " novel%n"
```

If you want to have a display function both publications and pixels, you simply add the word overloaded to the dynamic functions in each case:

```  define dynamic overloaded string function
display (value publication p)
as
return p:name || "%n"

define overriding string function
display (value novel n)
as
output n:name || " a " || n:genre || " novel%n"

define dynamic overloaded string function
display (value point p)
as
return "d" % p:x || ", " || "d" % p:y

define overriding string function
display (value pixel p)
as
return "d" % p:x || ", " || "d" % p:y || ": " || p:color
```

Notice that only the `dynamic` functions are declared `overloaded`, not the `overriding` functions. The appropriate dynamic function to call can be determined by OmniMark at compile time, which is what the `overloaded` keyword indicates. The appropriate overriding function for that type is then determined at runtime.

### Dynamic and conversion functions working together

It is often useful to create `display` functions for the `record` types that you create. The `display` functions discussed above are all defined as `string` functions, which makes it easy to call them with the `output` keyword or to feed them to any other context that accepts a stream of text:

```     repeat over p as p
output display (p)
again
```

However, it would be even neater to simply `output` (or `scan`, or generally use an object as a source) without specifically invoking the `display` function:

```     repeat over p as p
output p
again
```

You can do this by writing a `conversion-function` that calls a `dynamic` function:

```  define string conversion-function value point p
as
return display (p)
```

This technique is useful because it is not possible to write a conversion function for every member of a set of extended types. However, by writing a dynamic set of `display` functions for a type and its extensions, you can use a single conversion function for the entire type hierarchy, as shown above.