Values can be given names using `let`

:

```
# let a = 1;;
val a : int = 1
```

You can use similar syntax to define a function. Just provide additional parameters for the arguments.

```
# let add arg1 arg2 = arg1 + arg2;;
val add : int -> int -> int = <fun>
```

We can call it like this:

```
# add 1 2;;
- : int = 3
```

We can pass values in directly like that, or we can pass values bound to names:

```
# add a 2;;
- : int = 3
```

The line that the interpreter gives us after we define something is the value of the object with its type signature. When we gave it a simple value bound to `a`

, it came back with:

```
val a : int = 1
```

Which means `a`

is an `int`

, and its value is `1`

.

The type signature of our function is a little more complicated:

```
val add : int -> int -> int = <fun>
```

The type signature of `add`

looks like a bunch of ints and arrows. This is because a function that takes two arguments is actually a function which just takes one argument, but returns another function that takes the next argument. You could instead read it like this:

```
val add : int -> (int -> int) = <fun>
```

This is useful when we want to create different sorts of functions on the fly. For example, a function that adds 5 to everything:

```
# let add_five = add 5;;
val add_five : int -> int = <fun>
# add_five 5;;
- : int = 10
# add_five 10;;
- : int = 15
```